diff options
author | Anthony DiGirolamo <tonymd@google.com> | 2022-03-06 10:13:51 -0800 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-03-16 18:18:35 +0000 |
commit | 6e6f440f401b3ff386efcc313dfefc40ebc1fdda (patch) | |
tree | c20001985094a1746e7cbc8ed310f3868ae81e3c | |
parent | 86698c0b9620febe11cc274a44c9457e6127dd62 (diff) | |
download | pigweed-6e6f440f401b3ff386efcc313dfefc40ebc1fdda.tar.gz |
pw_console: Fuzzy command runner dialog
- New command runner for searching and running menu item actions
- Open logger menu converted to a command runner action instead of a
large nested submenu.
- Renamed some menu items for better searchability
- Removed unused WindowPane after_render_hooks
- border.py now accepts a title to display in the upper left.
- Numerous fixes to window focus behavior when opening and closing the
command runner dialog.
- Added 'Copy all Python Input' and Output menu options.
Change-Id: I1430dd3215fa45eee48e00d40ec309bb6b1b8f10
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/86900
Reviewed-by: Chad Norvell <chadnorvell@google.com>
Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
21 files changed, 3116 insertions, 182 deletions
diff --git a/pw_console/BUILD.gn b/pw_console/BUILD.gn index 119377c4b..eee9a4ff2 100644 --- a/pw_console/BUILD.gn +++ b/pw_console/BUILD.gn @@ -19,6 +19,7 @@ import("$dir_pw_docgen/docs.gni") pw_doc_group("docs") { inputs = [ "images/serial_debug.svg", + "images/command_runner_main_menu.svg", "images/calculator_plugin.png", "images/clock_plugin1.png", "images/clock_plugin2.png", diff --git a/pw_console/images/command_runner_main_menu.svg b/pw_console/images/command_runner_main_menu.svg new file mode 100644 index 000000000..4ef98ef2a --- /dev/null +++ b/pw_console/images/command_runner_main_menu.svg @@ -0,0 +1,1984 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1428pt" height="682pt" viewBox="0 0 1428 682" version="1.1"> +<defs> +<g> +<symbol overflow="visible" id="glyph0-0"> +<path style="stroke:none;" d="M 3.203125 -1.046875 L 10.796875 -1.046875 L 10.796875 -19.8125 L 3.203125 -19.8125 Z M 1.265625 0.875 L 1.265625 -21.734375 L 12.734375 -21.734375 L 12.734375 0.875 Z M 7.59375 -9.09375 L 7.59375 -8.375 L 5.671875 -8.375 L 5.671875 -9.109375 C 5.671875 -9.796875 5.878906 -10.441406 6.296875 -11.046875 L 7.828125 -13.296875 C 8.097656 -13.679688 8.234375 -14.035156 8.234375 -14.359375 C 8.234375 -14.816406 8.097656 -15.207031 7.828125 -15.53125 C 7.566406 -15.851562 7.210938 -16.015625 6.765625 -16.015625 C 5.960938 -16.015625 5.34375 -15.484375 4.90625 -14.421875 L 3.34375 -15.34375 C 4.1875 -16.957031 5.332031 -17.765625 6.78125 -17.765625 C 7.75 -17.765625 8.550781 -17.4375 9.1875 -16.78125 C 9.820312 -16.132812 10.140625 -15.320312 10.140625 -14.34375 C 10.140625 -13.644531 9.898438 -12.941406 9.421875 -12.234375 L 7.8125 -9.890625 C 7.664062 -9.679688 7.59375 -9.414062 7.59375 -9.09375 Z M 6.78125 -6.75 C 7.144531 -6.75 7.457031 -6.617188 7.71875 -6.359375 C 7.988281 -6.109375 8.125 -5.796875 8.125 -5.421875 C 8.125 -5.046875 7.988281 -4.726562 7.71875 -4.46875 C 7.457031 -4.207031 7.144531 -4.078125 6.78125 -4.078125 C 6.394531 -4.078125 6.070312 -4.207031 5.8125 -4.46875 C 5.5625 -4.726562 5.4375 -5.046875 5.4375 -5.421875 C 5.4375 -5.796875 5.5625 -6.109375 5.8125 -6.359375 C 6.070312 -6.617188 6.394531 -6.75 6.78125 -6.75 Z M 6.78125 -6.75 "/> +</symbol> +<symbol overflow="visible" id="glyph0-1"> +<path style="stroke:none;" d=""/> +</symbol> +<symbol overflow="visible" id="glyph0-2"> +<path style="stroke:none;" d="M 11.546875 1.8125 L 4.296875 1.8125 L 4.296875 -22.671875 L 11.546875 -22.671875 L 11.546875 -20.609375 L 6.625 -20.609375 L 6.625 -0.265625 L 11.546875 -0.265625 Z M 11.546875 1.8125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-3"> +<path style="stroke:none;" d="M 12.8125 -18.875 L 5.25 -18.875 L 5.25 -12.125 L 11.328125 -12.125 L 11.328125 -10.140625 L 5.25 -10.140625 L 5.25 0 L 2.921875 0 L 2.921875 -20.859375 L 12.8125 -20.859375 Z M 12.8125 -18.875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-4"> +<path style="stroke:none;" d="M 8.484375 -20.734375 C 8.484375 -20.234375 8.3125 -19.804688 7.96875 -19.453125 C 7.632812 -19.109375 7.210938 -18.9375 6.703125 -18.9375 C 6.191406 -18.9375 5.765625 -19.109375 5.421875 -19.453125 C 5.078125 -19.804688 4.90625 -20.234375 4.90625 -20.734375 C 4.90625 -21.222656 5.078125 -21.640625 5.421875 -21.984375 C 5.765625 -22.335938 6.191406 -22.515625 6.703125 -22.515625 C 7.210938 -22.515625 7.632812 -22.335938 7.96875 -21.984375 C 8.3125 -21.640625 8.484375 -21.222656 8.484375 -20.734375 Z M 12 0 L 2.25 0 L 2.25 -1.984375 L 5.96875 -1.984375 L 5.96875 -13.5 L 3.296875 -13.5 L 3.296875 -15.484375 L 8.296875 -15.484375 L 8.296875 -1.984375 L 12 -1.984375 Z M 12 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-5"> +<path style="stroke:none;" d="M 11.875 0 L 2.125 0 L 2.125 -1.984375 L 5.84375 -1.984375 L 5.84375 -18.875 L 3.1875 -18.875 L 3.1875 -20.859375 L 8.171875 -20.859375 L 8.171875 -1.984375 L 11.875 -1.984375 Z M 11.875 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-6"> +<path style="stroke:none;" d="M 12.203125 -7.28125 L 4.109375 -7.28125 L 4.109375 -6.8125 C 4.109375 -4.8125 4.398438 -3.484375 4.984375 -2.828125 C 5.566406 -2.171875 6.359375 -1.84375 7.359375 -1.84375 C 8.628906 -1.84375 9.644531 -2.488281 10.40625 -3.78125 L 12.296875 -2.578125 C 11.109375 -0.679688 9.410156 0.265625 7.203125 0.265625 C 5.628906 0.265625 4.332031 -0.296875 3.3125 -1.421875 C 2.289062 -2.554688 1.78125 -4.351562 1.78125 -6.8125 L 1.78125 -8.6875 C 1.78125 -11.132812 2.289062 -12.925781 3.3125 -14.0625 C 4.332031 -15.195312 5.5625 -15.765625 7 -15.765625 C 8.53125 -15.765625 9.78125 -15.238281 10.75 -14.1875 C 11.71875 -13.144531 12.203125 -11.441406 12.203125 -9.078125 Z M 9.890625 -9.328125 C 9.890625 -10.898438 9.617188 -12.015625 9.078125 -12.671875 C 8.535156 -13.328125 7.84375 -13.65625 7 -13.65625 C 6.195312 -13.65625 5.515625 -13.328125 4.953125 -12.671875 C 4.390625 -12.015625 4.109375 -10.898438 4.109375 -9.328125 Z M 9.890625 -9.328125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-7"> +<path style="stroke:none;" d="M 9.703125 1.8125 L 2.46875 1.8125 L 2.46875 -0.265625 L 7.375 -0.265625 L 7.375 -20.609375 L 2.46875 -20.609375 L 2.46875 -22.671875 L 9.703125 -22.671875 Z M 9.703125 1.8125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-8"> +<path style="stroke:none;" d="M 12.203125 0 L 2.578125 0 L 2.578125 -20.859375 L 12.203125 -20.859375 L 12.203125 -18.875 L 4.90625 -18.875 L 4.90625 -12.125 L 10.296875 -12.125 L 10.296875 -10.140625 L 4.90625 -10.140625 L 4.90625 -1.984375 L 12.203125 -1.984375 Z M 12.203125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-9"> +<path style="stroke:none;" d="M 1.59375 -8.8125 C 1.59375 -11.28125 2.03125 -13.054688 2.90625 -14.140625 C 3.789062 -15.222656 4.847656 -15.765625 6.078125 -15.765625 C 7.671875 -15.765625 8.875 -15.046875 9.6875 -13.609375 L 9.6875 -20.859375 L 12 -20.859375 L 12 0 L 9.6875 0 L 9.6875 -1.859375 C 8.875 -0.441406 7.671875 0.265625 6.078125 0.265625 C 4.847656 0.265625 3.789062 -0.269531 2.90625 -1.34375 C 2.03125 -2.425781 1.59375 -4.203125 1.59375 -6.671875 Z M 3.984375 -6.671875 C 3.984375 -4.878906 4.207031 -3.625 4.65625 -2.90625 C 5.113281 -2.195312 5.78125 -1.84375 6.65625 -1.84375 C 8.1875 -1.84375 9.195312 -2.867188 9.6875 -4.921875 L 9.6875 -10.4375 C 9.207031 -12.582031 8.195312 -13.65625 6.65625 -13.65625 C 5.78125 -13.65625 5.113281 -13.296875 4.65625 -12.578125 C 4.207031 -11.867188 3.984375 -10.613281 3.984375 -8.8125 Z M 3.984375 -6.671875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-10"> +<path style="stroke:none;" d="M 12.953125 -2.15625 C 11.867188 -0.539062 10.414062 0.265625 8.59375 0.265625 C 7.394531 0.265625 6.382812 -0.140625 5.5625 -0.953125 C 4.75 -1.773438 4.34375 -2.984375 4.34375 -4.578125 L 4.34375 -13.5 L 1.75 -13.5 L 1.75 -15.484375 L 4.34375 -15.484375 L 4.34375 -20.859375 L 6.671875 -20.859375 L 6.671875 -15.484375 L 11.890625 -15.484375 L 11.890625 -13.5 L 6.671875 -13.5 L 6.671875 -4.4375 C 6.671875 -3.582031 6.851562 -2.9375 7.21875 -2.5 C 7.582031 -2.0625 8.085938 -1.84375 8.734375 -1.84375 C 9.804688 -1.84375 10.625 -2.378906 11.1875 -3.453125 Z M 12.953125 -2.15625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-11"> +<path style="stroke:none;" d="M 5.6875 0 L 3.109375 -9.609375 C 1.941406 -13.910156 1.359375 -17.273438 1.359375 -19.703125 L 1.359375 -20.859375 L 3.6875 -20.859375 L 3.6875 -19.703125 C 3.6875 -17.691406 4.125 -14.804688 5 -11.046875 L 7 -2.609375 L 9 -11.046875 C 9.875 -14.804688 10.3125 -17.691406 10.3125 -19.703125 L 10.3125 -20.859375 L 12.640625 -20.859375 L 12.640625 -19.703125 C 12.640625 -17.273438 12.054688 -13.910156 10.890625 -9.609375 L 8.3125 0 Z M 5.6875 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-12"> +<path style="stroke:none;" d="M 9.578125 -1.28125 L 10.125 -6.296875 C 10.351562 -8.390625 10.46875 -10.53125 10.46875 -12.71875 L 10.46875 -15.484375 L 12.75 -15.484375 L 12.75 -13.421875 C 12.75 -11.554688 12.484375 -9.179688 11.953125 -6.296875 L 10.796875 0 L 8.609375 0 L 7 -6.96875 L 5.390625 0 L 3.203125 0 L 2.046875 -6.296875 C 1.523438 -9.179688 1.265625 -11.554688 1.265625 -13.421875 L 1.265625 -15.484375 L 3.53125 -15.484375 L 3.53125 -12.71875 C 3.53125 -10.53125 3.644531 -8.390625 3.875 -6.296875 L 4.421875 -1.28125 L 6.265625 -9.25 L 7.734375 -9.25 Z M 9.578125 -1.28125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-13"> +<path style="stroke:none;" d="M 9.734375 -1.265625 L 10.09375 -6.1875 C 10.226562 -8.007812 10.296875 -10.070312 10.296875 -12.375 L 10.296875 -20.859375 L 12.625 -20.859375 L 12.625 -15.828125 C 12.625 -12.398438 12.375 -9.1875 11.875 -6.1875 L 10.90625 0 L 8.71875 0 L 7 -8.078125 L 5.28125 0 L 3.09375 0 L 2.125 -6.1875 C 1.625 -9.1875 1.375 -12.398438 1.375 -15.828125 L 1.375 -20.859375 L 3.703125 -20.859375 L 3.703125 -12.375 C 3.703125 -10.070312 3.769531 -8.007812 3.90625 -6.1875 L 4.265625 -1.265625 L 6.265625 -10.671875 L 7.734375 -10.671875 Z M 9.734375 -1.265625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-14"> +<path style="stroke:none;" d="M 12.015625 0 L 9.6875 0 L 9.6875 -10.03125 C 9.6875 -11.375 9.476562 -12.304688 9.0625 -12.828125 C 8.644531 -13.359375 8.070312 -13.625 7.34375 -13.625 C 5.8125 -13.625 4.800781 -12.570312 4.3125 -10.46875 L 4.3125 0 L 1.984375 0 L 1.984375 -15.484375 L 4.3125 -15.484375 L 4.3125 -13.5 C 5.300781 -15.007812 6.503906 -15.765625 7.921875 -15.765625 C 9.066406 -15.765625 10.035156 -15.335938 10.828125 -14.484375 C 11.617188 -13.628906 12.015625 -12.191406 12.015625 -10.171875 Z M 12.015625 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-15"> +<path style="stroke:none;" d="M 12.21875 -6.703125 C 12.21875 -4.328125 11.726562 -2.570312 10.75 -1.4375 C 9.78125 -0.300781 8.53125 0.265625 7 0.265625 C 5.46875 0.265625 4.21875 -0.300781 3.25 -1.4375 C 2.28125 -2.570312 1.796875 -4.328125 1.796875 -6.703125 L 1.796875 -8.8125 C 1.796875 -11.175781 2.28125 -12.925781 3.25 -14.0625 C 4.21875 -15.195312 5.46875 -15.765625 7 -15.765625 C 8.53125 -15.765625 9.78125 -15.195312 10.75 -14.0625 C 11.726562 -12.925781 12.21875 -11.175781 12.21875 -8.8125 Z M 9.90625 -6.703125 L 9.90625 -8.8125 C 9.90625 -10.632812 9.628906 -11.894531 9.078125 -12.59375 C 8.535156 -13.300781 7.84375 -13.65625 7 -13.65625 C 6.15625 -13.65625 5.460938 -13.300781 4.921875 -12.59375 C 4.378906 -11.894531 4.109375 -10.632812 4.109375 -8.8125 L 4.109375 -6.703125 C 4.109375 -4.867188 4.378906 -3.597656 4.921875 -2.890625 C 5.460938 -2.191406 6.15625 -1.84375 7 -1.84375 C 7.84375 -1.84375 8.535156 -2.191406 9.078125 -2.890625 C 9.628906 -3.597656 9.90625 -4.867188 9.90625 -6.703125 Z M 9.90625 -6.703125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-16"> +<path style="stroke:none;" d="M 7.0625 -1.796875 C 8.019531 -1.796875 8.75 -2.023438 9.25 -2.484375 C 9.75 -2.941406 10 -3.5 10 -4.15625 C 10 -5.0625 9.445312 -5.765625 8.34375 -6.265625 L 5.359375 -7.625 C 3.503906 -8.5 2.578125 -9.75 2.578125 -11.375 C 2.578125 -12.644531 3.03125 -13.691406 3.9375 -14.515625 C 4.851562 -15.347656 6.035156 -15.765625 7.484375 -15.765625 C 9.546875 -15.765625 11.128906 -14.8125 12.234375 -12.90625 L 10.34375 -11.765625 C 9.757812 -13.054688 8.804688 -13.703125 7.484375 -13.703125 C 6.691406 -13.703125 6.0625 -13.5 5.59375 -13.09375 C 5.132812 -12.695312 4.90625 -12.203125 4.90625 -11.609375 C 4.90625 -10.816406 5.421875 -10.175781 6.453125 -9.6875 L 9.265625 -8.375 C 11.296875 -7.425781 12.3125 -5.984375 12.3125 -4.046875 C 12.3125 -2.898438 11.835938 -1.894531 10.890625 -1.03125 C 9.941406 -0.164062 8.65625 0.265625 7.03125 0.265625 C 4.75 0.265625 2.96875 -0.789062 1.6875 -2.90625 L 3.59375 -4.0625 C 4.351562 -2.550781 5.507812 -1.796875 7.0625 -1.796875 Z M 7.0625 -1.796875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-17"> +<path style="stroke:none;" d="M 12.015625 0 L 9.6875 0 L 9.6875 -10.4375 L 4.3125 -10.4375 L 4.3125 0 L 1.984375 0 L 1.984375 -20.859375 L 4.3125 -20.859375 L 4.3125 -12.421875 L 9.6875 -12.421875 L 9.6875 -20.859375 L 12.015625 -20.859375 Z M 12.015625 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-18"> +<path style="stroke:none;" d="M 12.421875 -6.65625 C 12.421875 -4.21875 11.953125 -2.453125 11.015625 -1.359375 C 10.085938 -0.273438 9.054688 0.265625 7.921875 0.265625 C 6.328125 0.265625 5.128906 -0.457031 4.328125 -1.90625 L 4.328125 4.828125 L 2 4.828125 L 2 -15.484375 L 4.328125 -15.484375 L 4.328125 -13.640625 C 5.128906 -15.054688 6.328125 -15.765625 7.921875 -15.765625 C 9.054688 -15.765625 10.085938 -15.222656 11.015625 -14.140625 C 11.953125 -13.066406 12.421875 -11.289062 12.421875 -8.8125 Z M 10.015625 -8.8125 C 10.015625 -10.625 9.765625 -11.882812 9.265625 -12.59375 C 8.765625 -13.300781 8.125 -13.65625 7.34375 -13.65625 C 5.8125 -13.65625 4.804688 -12.59375 4.328125 -10.46875 L 4.328125 -5.046875 C 4.796875 -2.910156 5.800781 -1.84375 7.34375 -1.84375 C 8.125 -1.84375 8.765625 -2.203125 9.265625 -2.921875 C 9.765625 -3.640625 10.015625 -4.882812 10.015625 -6.65625 Z M 10.015625 -8.8125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-19"> +<path style="stroke:none;" d="M 12.953125 -3.09375 C 11.648438 -0.851562 9.878906 0.265625 7.640625 0.265625 C 6.128906 0.265625 4.851562 -0.238281 3.8125 -1.25 C 2.769531 -2.269531 2.25 -4.132812 2.25 -6.84375 L 2.25 -14.046875 C 2.25 -16.679688 2.769531 -18.523438 3.8125 -19.578125 C 4.851562 -20.640625 6.117188 -21.171875 7.609375 -21.171875 C 9.953125 -21.171875 11.6875 -20.039062 12.8125 -17.78125 L 10.90625 -16.625 C 10.21875 -18.238281 9.125 -19.046875 7.625 -19.046875 C 6.757812 -19.046875 6.035156 -18.726562 5.453125 -18.09375 C 4.878906 -17.457031 4.59375 -16.109375 4.59375 -14.046875 L 4.59375 -6.84375 C 4.59375 -4.78125 4.878906 -3.429688 5.453125 -2.796875 C 6.035156 -2.160156 6.757812 -1.84375 7.625 -1.84375 C 9.125 -1.84375 10.265625 -2.6875 11.046875 -4.375 Z M 12.953125 -3.09375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-20"> +<path style="stroke:none;" d="M 12.453125 -18.875 L 8.15625 -18.875 L 8.15625 0 L 5.84375 0 L 5.84375 -18.875 L 1.546875 -18.875 L 1.546875 -20.859375 L 12.453125 -20.859375 Z M 12.453125 -18.875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-21"> +<path style="stroke:none;" d="M 12.328125 0 L 10.015625 0 L 10.015625 -5.515625 C 10.015625 -9.023438 10.148438 -13.148438 10.421875 -17.890625 L 7.71875 -9.25 L 6.28125 -9.25 L 3.578125 -17.890625 C 3.859375 -13.148438 4 -9.023438 4 -5.515625 L 4 0 L 1.671875 0 L 1.671875 -20.859375 L 4 -20.859375 L 7 -12.203125 L 10.015625 -20.859375 L 12.328125 -20.859375 Z M 12.328125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-22"> +<path style="stroke:none;" d="M 12.53125 -4.875 C 12.53125 -3.457031 12.054688 -2.242188 11.109375 -1.234375 C 10.171875 -0.234375 8.867188 0.265625 7.203125 0.265625 C 4.578125 0.265625 2.660156 -0.878906 1.453125 -3.171875 L 3.171875 -4.46875 C 4.078125 -2.71875 5.414062 -1.84375 7.1875 -1.84375 C 8.007812 -1.84375 8.71875 -2.09375 9.3125 -2.59375 C 9.90625 -3.101562 10.203125 -3.859375 10.203125 -4.859375 C 10.203125 -5.671875 9.691406 -6.554688 8.671875 -7.515625 L 4.1875 -11.703125 C 2.9375 -12.878906 2.3125 -14.359375 2.3125 -16.140625 C 2.3125 -17.554688 2.769531 -18.75 3.6875 -19.71875 C 4.613281 -20.6875 5.878906 -21.171875 7.484375 -21.171875 C 9.566406 -21.171875 11.253906 -20.21875 12.546875 -18.3125 L 10.765625 -16.90625 C 9.992188 -18.332031 8.90625 -19.046875 7.5 -19.046875 C 6.6875 -19.046875 6.007812 -18.8125 5.46875 -18.34375 C 4.925781 -17.882812 4.65625 -17.148438 4.65625 -16.140625 C 4.65625 -15.109375 5.0625 -14.210938 5.875 -13.453125 L 10.34375 -9.296875 C 11.800781 -7.910156 12.53125 -6.4375 12.53125 -4.875 Z M 12.53125 -4.875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-23"> +<path style="stroke:none;" d="M 11.671875 0 L 9.359375 0 L 9.359375 -1.75 C 8.367188 -0.40625 7.125 0.265625 5.625 0.265625 C 4.351562 0.265625 3.328125 -0.164062 2.546875 -1.03125 C 1.765625 -1.90625 1.375 -3 1.375 -4.3125 C 1.375 -5.65625 1.863281 -6.78125 2.84375 -7.6875 C 3.820312 -8.601562 5.253906 -9.0625 7.140625 -9.0625 L 9.359375 -9.0625 L 9.359375 -10.734375 C 9.359375 -12.679688 8.429688 -13.65625 6.578125 -13.65625 C 5.210938 -13.65625 4.191406 -13.054688 3.515625 -11.859375 L 1.75 -13.171875 C 2.96875 -14.898438 4.582031 -15.765625 6.59375 -15.765625 C 8.070312 -15.765625 9.285156 -15.335938 10.234375 -14.484375 C 11.191406 -13.640625 11.671875 -12.390625 11.671875 -10.734375 Z M 9.359375 -3.640625 L 9.359375 -7.1875 L 7.140625 -7.1875 C 6.023438 -7.1875 5.1875 -6.925781 4.625 -6.40625 C 4.0625 -5.894531 3.78125 -5.195312 3.78125 -4.3125 C 3.78125 -2.664062 4.582031 -1.84375 6.1875 -1.84375 C 7.457031 -1.84375 8.515625 -2.441406 9.359375 -3.640625 Z M 9.359375 -3.640625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-24"> +<path style="stroke:none;" d="M 13 -12.859375 L 10.984375 -11.96875 C 10.523438 -13.09375 9.753906 -13.65625 8.671875 -13.65625 C 6.390625 -13.65625 5.25 -11.535156 5.25 -7.296875 L 5.25 0 L 2.921875 0 L 2.921875 -15.484375 L 5.25 -15.484375 L 5.25 -13 C 6.164062 -14.84375 7.425781 -15.765625 9.03125 -15.765625 C 10.894531 -15.765625 12.21875 -14.796875 13 -12.859375 Z M 13 -12.859375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-25"> +<path style="stroke:none;" d="M 12.84375 -2.578125 C 11.65625 -0.679688 9.957031 0.265625 7.75 0.265625 C 6.164062 0.265625 4.863281 -0.296875 3.84375 -1.421875 C 2.820312 -2.554688 2.3125 -4.347656 2.3125 -6.796875 L 2.3125 -8.703125 C 2.3125 -11.140625 2.820312 -12.925781 3.84375 -14.0625 C 4.863281 -15.195312 6.164062 -15.765625 7.75 -15.765625 C 9.957031 -15.765625 11.65625 -14.8125 12.84375 -12.90625 L 10.953125 -11.71875 C 10.179688 -13.007812 9.160156 -13.65625 7.890625 -13.65625 C 6.898438 -13.65625 6.113281 -13.328125 5.53125 -12.671875 C 4.945312 -12.015625 4.65625 -10.691406 4.65625 -8.703125 L 4.65625 -6.796875 C 4.65625 -4.804688 4.945312 -3.484375 5.53125 -2.828125 C 6.113281 -2.171875 6.898438 -1.84375 7.890625 -1.84375 C 9.160156 -1.84375 10.179688 -2.488281 10.953125 -3.78125 Z M 12.84375 -2.578125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-26"> +<path style="stroke:none;" d="M 12.015625 0 L 9.6875 0 L 9.6875 -10.015625 C 9.6875 -11.398438 9.476562 -12.351562 9.0625 -12.875 C 8.644531 -13.394531 8.070312 -13.65625 7.34375 -13.65625 C 5.8125 -13.65625 4.800781 -12.59375 4.3125 -10.46875 L 4.3125 0 L 1.984375 0 L 1.984375 -20.859375 L 4.3125 -20.859375 L 4.3125 -13.625 C 5.300781 -15.050781 6.503906 -15.765625 7.921875 -15.765625 C 9.066406 -15.765625 10.035156 -15.335938 10.828125 -14.484375 C 11.617188 -13.628906 12.015625 -12.179688 12.015625 -10.140625 Z M 12.015625 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-27"> +<path style="stroke:none;" d="M 12.015625 0 L 9.6875 0 L 9.6875 -2.015625 C 8.695312 -0.492188 7.492188 0.265625 6.078125 0.265625 C 4.929688 0.265625 3.960938 -0.164062 3.171875 -1.03125 C 2.378906 -1.90625 1.984375 -3.460938 1.984375 -5.703125 L 1.984375 -15.484375 L 4.3125 -15.484375 L 4.3125 -5.703125 C 4.3125 -4.203125 4.519531 -3.179688 4.9375 -2.640625 C 5.351562 -2.109375 5.925781 -1.84375 6.65625 -1.84375 C 8.1875 -1.84375 9.195312 -2.851562 9.6875 -4.875 L 9.6875 -15.484375 L 12.015625 -15.484375 Z M 12.015625 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-28"> +<path style="stroke:none;" d="M 12.28125 -7.296875 L 1.71875 -7.296875 L 1.71875 -9.28125 L 12.28125 -9.28125 Z M 12.28125 -7.296875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-29"> +<path style="stroke:none;" d="M 12.8125 0 L 10.484375 0 C 10.410156 -1.132812 9.851562 -2.460938 8.8125 -3.984375 L 6.5 -7.28125 L 4.765625 -5.1875 L 4.765625 0 L 2.453125 0 L 2.453125 -20.859375 L 4.765625 -20.859375 L 4.765625 -8.046875 L 8.1875 -12.25 C 9.332031 -13.65625 9.914062 -14.734375 9.9375 -15.484375 L 12.265625 -15.484375 L 12.234375 -14.96875 C 12.191406 -14.15625 11.421875 -12.835938 9.921875 -11.015625 L 8.0625 -8.734375 L 10.46875 -5.25 C 11.9375 -3.125 12.703125 -1.554688 12.765625 -0.546875 Z M 12.8125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-30"> +<path style="stroke:none;" d="M 4.96875 0 L 2.640625 0 L 2.640625 -20.859375 L 7.1875 -20.859375 C 9.039062 -20.859375 10.441406 -20.351562 11.390625 -19.34375 C 12.335938 -18.34375 12.8125 -17.003906 12.8125 -15.328125 C 12.8125 -13.441406 12.289062 -11.992188 11.25 -10.984375 C 10.207031 -9.972656 8.851562 -9.46875 7.1875 -9.46875 L 4.96875 -9.46875 Z M 4.96875 -11.453125 L 7.171875 -11.453125 C 8.242188 -11.453125 9.050781 -11.722656 9.59375 -12.265625 C 10.132812 -12.804688 10.40625 -13.828125 10.40625 -15.328125 C 10.40625 -16.609375 10.15625 -17.519531 9.65625 -18.0625 C 9.164062 -18.601562 8.335938 -18.875 7.171875 -18.875 L 4.96875 -18.875 Z M 4.96875 -11.453125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-31"> +<path style="stroke:none;" d="M 12.671875 -8.5625 C 12.671875 -5.832031 12.046875 -3.722656 10.796875 -2.234375 C 9.554688 -0.742188 7.875 0 5.75 0 L 2.296875 0 L 2.296875 -20.859375 L 5.75 -20.859375 C 7.875 -20.859375 9.554688 -20.15625 10.796875 -18.75 C 12.046875 -17.351562 12.671875 -15.300781 12.671875 -12.59375 Z M 10.28125 -8.5625 L 10.28125 -12.59375 C 10.28125 -14.71875 9.875 -16.296875 9.0625 -17.328125 C 8.25 -18.359375 7.144531 -18.875 5.75 -18.875 L 4.609375 -18.875 L 4.609375 -1.984375 L 5.75 -1.984375 C 7.144531 -1.984375 8.25 -2.535156 9.0625 -3.640625 C 9.875 -4.742188 10.28125 -6.382812 10.28125 -8.5625 Z M 10.28125 -8.5625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-32"> +<path style="stroke:none;" d="M 12.421875 -6.671875 C 12.421875 -4.203125 11.976562 -2.425781 11.09375 -1.34375 C 10.207031 -0.269531 9.148438 0.265625 7.921875 0.265625 C 6.328125 0.265625 5.128906 -0.441406 4.328125 -1.859375 L 4.328125 0 L 2 0 L 2 -20.859375 L 4.328125 -20.859375 L 4.328125 -13.609375 C 5.128906 -15.046875 6.328125 -15.765625 7.921875 -15.765625 C 9.148438 -15.765625 10.207031 -15.222656 11.09375 -14.140625 C 11.976562 -13.054688 12.421875 -11.28125 12.421875 -8.8125 Z M 10.015625 -6.671875 L 10.015625 -8.8125 C 10.015625 -10.613281 9.785156 -11.867188 9.328125 -12.578125 C 8.878906 -13.296875 8.21875 -13.65625 7.34375 -13.65625 C 5.800781 -13.65625 4.796875 -12.625 4.328125 -10.5625 L 4.328125 -4.921875 C 4.804688 -2.867188 5.8125 -1.84375 7.34375 -1.84375 C 8.21875 -1.84375 8.878906 -2.195312 9.328125 -2.90625 C 9.785156 -3.625 10.015625 -4.878906 10.015625 -6.671875 Z M 10.015625 -6.671875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-33"> +<path style="stroke:none;" d="M 13.046875 -13.625 L 12.234375 -13.625 L 10.984375 -13.75 C 11.671875 -12.90625 12.015625 -12.046875 12.015625 -11.171875 C 12.015625 -9.972656 11.582031 -8.976562 10.71875 -8.1875 C 9.851562 -7.394531 8.671875 -7 7.171875 -7 C 6.609375 -7 6.097656 -7 5.640625 -7 C 4.898438 -6.519531 4.53125 -6.054688 4.53125 -5.609375 C 4.53125 -5.140625 4.675781 -4.789062 4.96875 -4.5625 C 5.257812 -4.34375 5.738281 -4.234375 6.40625 -4.234375 L 7.703125 -4.234375 C 9.628906 -4.234375 11.023438 -3.820312 11.890625 -3 C 12.753906 -2.1875 13.1875 -1.15625 13.1875 0.09375 C 13.1875 1.5 12.632812 2.660156 11.53125 3.578125 C 10.4375 4.492188 8.988281 4.953125 7.1875 4.953125 C 5.3125 4.953125 3.882812 4.523438 2.90625 3.671875 C 1.9375 2.828125 1.453125 1.800781 1.453125 0.59375 C 1.453125 -0.988281 2.25 -2.1875 3.84375 -3 C 2.664062 -3.488281 2.078125 -4.238281 2.078125 -5.25 C 2.078125 -6.269531 2.703125 -7.132812 3.953125 -7.84375 C 2.671875 -8.707031 2.03125 -9.898438 2.03125 -11.421875 C 2.03125 -12.679688 2.484375 -13.707031 3.390625 -14.5 C 4.296875 -15.300781 5.554688 -15.703125 7.171875 -15.703125 C 7.648438 -15.703125 8.804688 -15.628906 10.640625 -15.484375 L 13.046875 -15.484375 Z M 9.78125 -11.4375 C 9.78125 -12.050781 9.550781 -12.59375 9.09375 -13.0625 C 8.632812 -13.53125 7.953125 -13.765625 7.046875 -13.765625 C 6.109375 -13.765625 5.414062 -13.539062 4.96875 -13.09375 C 4.519531 -12.65625 4.296875 -12.085938 4.296875 -11.390625 C 4.296875 -10.585938 4.53125 -9.972656 5 -9.546875 C 5.476562 -9.128906 6.144531 -8.921875 7 -8.921875 C 7.925781 -8.921875 8.617188 -9.140625 9.078125 -9.578125 C 9.546875 -10.015625 9.78125 -10.632812 9.78125 -11.4375 Z M 10.78125 0.09375 C 10.78125 -0.59375 10.554688 -1.132812 10.109375 -1.53125 C 9.660156 -1.9375 8.859375 -2.140625 7.703125 -2.140625 L 6.765625 -2.140625 C 5.710938 -2.140625 4.960938 -1.898438 4.515625 -1.421875 C 4.066406 -0.941406 3.84375 -0.328125 3.84375 0.421875 C 3.84375 1.203125 4.132812 1.800781 4.71875 2.21875 C 5.300781 2.644531 6.070312 2.859375 7.03125 2.859375 C 9.53125 2.859375 10.78125 1.9375 10.78125 0.09375 Z M 10.78125 0.09375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-34"> +<path style="stroke:none;" d="M 4.140625 2.5 L 5.921875 -2.125 L 2.703125 -10.015625 C 1.941406 -11.910156 1.53125 -13.332031 1.46875 -14.28125 L 1.390625 -15.484375 L 3.71875 -15.484375 L 3.78125 -14.375 C 3.820312 -13.738281 4.179688 -12.503906 4.859375 -10.671875 L 7 -4.828125 L 9.140625 -10.59375 C 9.804688 -12.457031 10.164062 -13.71875 10.21875 -14.375 L 10.28125 -15.484375 L 12.609375 -15.484375 L 12.53125 -14.28125 C 12.476562 -13.4375 12.066406 -12.015625 11.296875 -10.015625 L 6.359375 2.796875 C 6.179688 3.234375 6.078125 3.742188 6.046875 4.328125 L 6.015625 4.828125 L 3.6875 4.828125 L 3.71875 4.328125 C 3.757812 3.742188 3.898438 3.132812 4.140625 2.5 Z M 4.140625 2.5 "/> +</symbol> +<symbol overflow="visible" id="glyph0-35"> +<path style="stroke:none;" d="M 7.265625 -9.515625 L 4.84375 -9.515625 L 4.84375 0 L 2.515625 0 L 2.515625 -20.859375 L 7.0625 -20.859375 C 8.914062 -20.859375 10.289062 -20.359375 11.1875 -19.359375 C 12.09375 -18.359375 12.546875 -17.015625 12.546875 -15.328125 C 12.546875 -13.898438 12.253906 -12.722656 11.671875 -11.796875 C 11.097656 -10.878906 10.382812 -10.257812 9.53125 -9.9375 L 9.78125 -9.5625 C 11.507812 -6.863281 12.460938 -3.988281 12.640625 -0.9375 L 12.703125 0 L 10.375 0 L 10.34375 -0.71875 C 10.164062 -3.632812 9.253906 -6.378906 7.609375 -8.953125 Z M 4.84375 -11.484375 L 7.0625 -11.484375 C 8.132812 -11.484375 8.914062 -11.800781 9.40625 -12.4375 C 9.894531 -13.082031 10.140625 -14.050781 10.140625 -15.34375 C 10.140625 -16.613281 9.894531 -17.519531 9.40625 -18.0625 C 8.914062 -18.601562 8.132812 -18.875 7.0625 -18.875 L 4.84375 -18.875 Z M 4.84375 -11.484375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-36"> +<path style="stroke:none;" d="M 3.8125 -1.15625 L 3.8125 0 L 1.484375 0 L 1.484375 -1.15625 C 1.484375 -3.15625 2.082031 -6.519531 3.28125 -11.25 L 5.6875 -20.859375 L 8.3125 -20.859375 L 10.71875 -11.25 C 11.914062 -6.519531 12.515625 -3.15625 12.515625 -1.15625 L 12.515625 0 L 10.1875 0 L 10.1875 -1.15625 C 10.1875 -2.101562 10.054688 -3.34375 9.796875 -4.875 L 4.203125 -4.875 C 3.941406 -3.34375 3.8125 -2.101562 3.8125 -1.15625 Z M 7 -17.171875 L 5.265625 -9.953125 C 4.992188 -8.835938 4.757812 -7.804688 4.5625 -6.859375 L 9.421875 -6.859375 C 9.234375 -7.804688 9.003906 -8.835938 8.734375 -9.953125 Z M 7 -17.171875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-37"> +<path style="stroke:none;" d="M 12.8125 0 L 3.328125 0 L 3.328125 -20.859375 L 5.640625 -20.859375 L 5.640625 -1.984375 L 12.8125 -1.984375 Z M 12.8125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-38"> +<path style="stroke:none;" d="M 8.34375 0 L 5.65625 0 L 2.984375 -8.09375 C 2.054688 -10.863281 1.550781 -12.957031 1.46875 -14.375 L 1.390625 -15.484375 L 3.71875 -15.484375 L 3.78125 -14.375 C 3.863281 -13.03125 4.304688 -11.046875 5.109375 -8.421875 L 7 -2.1875 L 8.890625 -8.421875 C 9.691406 -11.046875 10.132812 -13.03125 10.21875 -14.375 L 10.28125 -15.484375 L 12.609375 -15.484375 L 12.53125 -14.375 C 12.445312 -12.957031 11.941406 -10.863281 11.015625 -8.09375 Z M 8.34375 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-39"> +<path style="stroke:none;" d="M 12.609375 -8.21875 L 10.125 -8.21875 L 6.984375 -17.765625 L 3.765625 -8.21875 L 1.375 -8.21875 L 5.765625 -20.859375 L 8.171875 -20.859375 Z M 12.609375 -8.21875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-40"> +<path style="stroke:none;" d="M 14 -13.703125 L 14 -7.125 L 10.296875 -7.125 L 10.296875 4.953125 L 3.703125 4.953125 L 3.703125 -13.703125 Z M 14 -13.703125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-41"> +<path style="stroke:none;" d="M 14.265625 -13.703125 L 14.265625 -7.125 L -0.265625 -7.125 L -0.265625 -13.703125 Z M 14.265625 -13.703125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-42"> +<path style="stroke:none;" d="M 11.453125 0 L 2.53125 0 L 2.53125 -1.984375 L 5.828125 -1.984375 L 5.828125 -18.875 L 3.234375 -18.875 L 3.234375 -20.859375 L 10.75 -20.859375 L 10.75 -18.875 L 8.15625 -18.875 L 8.15625 -1.984375 L 11.453125 -1.984375 Z M 11.453125 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-43"> +<path style="stroke:none;" d="M 12.65625 0 L 10.765625 0 L 10.765625 -11.6875 C 10.765625 -13.007812 10.375 -13.671875 9.59375 -13.671875 C 8.914062 -13.671875 8.363281 -13.160156 7.9375 -12.140625 L 7.9375 0 L 6.0625 0 L 6.0625 -11.6875 C 6.039062 -13.007812 5.726562 -13.671875 5.125 -13.671875 C 4.351562 -13.671875 3.726562 -13.160156 3.25 -12.140625 L 3.25 0 L 1.34375 0 L 1.34375 -15.484375 L 3.25 -15.484375 L 3.25 -13.953125 C 3.945312 -15.160156 4.804688 -15.765625 5.828125 -15.765625 C 6.742188 -15.765625 7.375 -15.160156 7.71875 -13.953125 C 8.375 -15.160156 9.195312 -15.765625 10.1875 -15.765625 C 11.832031 -15.765625 12.65625 -14.441406 12.65625 -11.796875 Z M 12.65625 0 "/> +</symbol> +<symbol overflow="visible" id="glyph0-44"> +<path style="stroke:none;" d="M 10.296875 -13.703125 L 10.296875 4.953125 L 3.703125 4.953125 L 3.703125 -7.125 L 0 -7.125 L 0 -13.703125 Z M 10.296875 -13.703125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-45"> +<path style="stroke:none;" d="M 10.296875 4.953125 L 3.703125 4.953125 L 3.703125 -25.765625 L 10.296875 -25.765625 Z M 10.296875 4.953125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-46"> +<path style="stroke:none;" d="M 1.59375 -13.4375 L 1.59375 -15.9375 L 12.9375 -9.765625 L 12.9375 -6.828125 L 1.59375 -0.640625 L 1.59375 -3.140625 L 11.234375 -8.296875 Z M 1.59375 -13.4375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-47"> +<path style="stroke:none;" d="M 12.171875 -6.515625 C 12.171875 -4.359375 11.648438 -2.6875 10.609375 -1.5 C 9.566406 -0.320312 8.300781 0.265625 6.8125 0.265625 C 4.550781 0.265625 2.847656 -0.804688 1.703125 -2.953125 L 3.609375 -4.21875 C 4.253906 -2.632812 5.316406 -1.84375 6.796875 -1.84375 C 7.597656 -1.84375 8.300781 -2.203125 8.90625 -2.921875 C 9.519531 -3.640625 9.828125 -4.835938 9.828125 -6.515625 C 9.828125 -8.203125 9.523438 -9.382812 8.921875 -10.0625 C 8.328125 -10.738281 7.351562 -11.078125 6 -11.078125 L 2.90625 -11.078125 L 2.90625 -20.859375 L 11.734375 -20.859375 L 11.734375 -18.875 L 5.234375 -18.875 L 5.234375 -13.1875 L 6.40625 -13.1875 C 8.132812 -13.1875 9.523438 -12.664062 10.578125 -11.625 C 11.640625 -10.59375 12.171875 -8.890625 12.171875 -6.515625 Z M 12.171875 -6.515625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-48"> +<path style="stroke:none;" d="M 9.6875 -2.421875 C 9.6875 -1.710938 9.429688 -1.085938 8.921875 -0.546875 C 8.410156 -0.00390625 7.765625 0.265625 6.984375 0.265625 C 6.203125 0.265625 5.5625 -0.00390625 5.0625 -0.546875 C 4.570312 -1.085938 4.328125 -1.710938 4.328125 -2.421875 C 4.328125 -3.117188 4.570312 -3.738281 5.0625 -4.28125 C 5.5625 -4.832031 6.203125 -5.109375 6.984375 -5.109375 C 7.765625 -5.109375 8.410156 -4.832031 8.921875 -4.28125 C 9.429688 -3.726562 9.6875 -3.109375 9.6875 -2.421875 Z M 9.6875 -13.078125 C 9.6875 -12.359375 9.429688 -11.726562 8.921875 -11.1875 C 8.410156 -10.65625 7.765625 -10.390625 6.984375 -10.390625 C 6.203125 -10.390625 5.5625 -10.65625 5.0625 -11.1875 C 4.570312 -11.726562 4.328125 -12.359375 4.328125 -13.078125 C 4.328125 -13.785156 4.570312 -14.410156 5.0625 -14.953125 C 5.5625 -15.492188 6.203125 -15.765625 6.984375 -15.765625 C 7.765625 -15.765625 8.410156 -15.488281 8.921875 -14.9375 C 9.429688 -14.394531 9.6875 -13.773438 9.6875 -13.078125 Z M 9.6875 -13.078125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-49"> +<path style="stroke:none;" d="M 3.5625 -7.390625 C 3.90625 -7.390625 4.191406 -7.1875 4.421875 -6.78125 C 4.984375 -5.882812 5.367188 -5.4375 5.578125 -5.4375 C 5.679688 -5.4375 5.75 -5.503906 5.78125 -5.640625 C 6.664062 -8.816406 7.515625 -11.3125 8.328125 -13.125 C 9.148438 -14.945312 9.847656 -16.269531 10.421875 -17.09375 C 11.078125 -18 11.707031 -18.453125 12.3125 -18.453125 C 12.46875 -18.453125 12.597656 -18.410156 12.703125 -18.328125 C 12.816406 -18.253906 12.875 -18.140625 12.875 -17.984375 C 12.875 -17.796875 12.753906 -17.507812 12.515625 -17.125 C 10.628906 -13.84375 8.894531 -9.082031 7.3125 -2.84375 C 7.1875 -2.425781 6.875 -2.117188 6.375 -1.921875 C 5.875 -1.722656 5.484375 -1.625 5.203125 -1.625 C 4.640625 -1.625 3.957031 -2.203125 3.15625 -3.359375 C 2.351562 -4.515625 1.953125 -5.25 1.953125 -5.5625 C 1.953125 -5.957031 2.148438 -6.359375 2.546875 -6.765625 C 2.953125 -7.179688 3.289062 -7.390625 3.5625 -7.390625 Z M 3.5625 -7.390625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-50"> +<path style="stroke:none;" d="M 12.5 -20.859375 L 3.75 1.75 L 1.484375 1.75 L 10.25 -20.859375 Z M 12.5 -20.859375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-51"> +<path style="stroke:none;" d="M 4.90625 -3.234375 C 4.175781 -2.210938 3.773438 -1.132812 3.703125 0 L 1.375 0 L 1.40625 -0.53125 C 1.46875 -1.550781 2.050781 -2.835938 3.15625 -4.390625 L 5.703125 -7.984375 L 3.515625 -11.09375 C 2.410156 -12.632812 1.828125 -13.921875 1.765625 -14.953125 L 1.75 -15.484375 L 4.078125 -15.484375 C 4.140625 -14.359375 4.535156 -13.28125 5.265625 -12.25 L 7 -9.8125 L 8.734375 -12.25 C 9.460938 -13.28125 9.859375 -14.359375 9.921875 -15.484375 L 12.25 -15.484375 L 12.234375 -14.953125 C 12.171875 -13.921875 11.585938 -12.632812 10.484375 -11.09375 L 8.28125 -7.984375 L 10.84375 -4.390625 C 11.945312 -2.835938 12.53125 -1.550781 12.59375 -0.53125 L 12.625 0 L 10.296875 0 C 10.222656 -1.132812 9.820312 -2.210938 9.09375 -3.234375 L 7 -6.171875 Z M 4.90625 -3.234375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-52"> +<path style="stroke:none;" d="M 11.0625 -17.859375 C 10.695312 -18.640625 10.019531 -19.03125 9.03125 -19.03125 C 8.382812 -19.03125 7.878906 -18.820312 7.515625 -18.40625 C 7.160156 -17.988281 6.984375 -17.242188 6.984375 -16.171875 L 6.984375 -14.609375 L 12.203125 -14.609375 L 12.203125 -12.640625 L 6.984375 -12.640625 L 6.984375 0 L 4.65625 0 L 4.65625 -12.640625 L 2.046875 -12.640625 L 2.046875 -14.609375 L 4.65625 -14.609375 L 4.65625 -16.03125 C 4.65625 -17.789062 5.0625 -19.082031 5.875 -19.90625 C 6.695312 -20.738281 7.703125 -21.15625 8.890625 -21.15625 C 10.710938 -21.15625 12.019531 -20.523438 12.8125 -19.265625 Z M 11.0625 -17.859375 "/> +</symbol> +<symbol overflow="visible" id="glyph0-53"> +<path style="stroke:none;" d="M 3.703125 -7.140625 L 3.703125 -25.765625 L 10.296875 -25.765625 L 10.296875 -13.703125 L 14 -13.703125 L 14 -7.125 Z M 3.703125 -7.140625 "/> +</symbol> +<symbol overflow="visible" id="glyph0-54"> +<path style="stroke:none;" d="M 0 -7.125 L 0 -13.703125 L 3.703125 -13.703125 L 3.703125 -25.765625 L 10.296875 -25.765625 L 10.296875 -7.125 Z M 0 -7.125 "/> +</symbol> +<symbol overflow="visible" id="glyph0-55"> +<path style="stroke:none;" d="M -0.265625 -9.421875 L -0.265625 -11.390625 L 14.265625 -11.390625 L 14.265625 -9.421875 Z M -0.265625 -9.421875 "/> +</symbol> +<symbol overflow="visible" id="glyph0-56"> +<path style="stroke:none;" d="M 0 -7.125 L 0 -9.109375 L 14 -9.109375 L 14 -7.125 Z M 0 -11.71875 L 0 -13.703125 L 14 -13.703125 L 14 -11.71875 Z M 0 -11.71875 "/> +</symbol> +</g> +</defs> +<g id="surface89756"> +<rect x="0" y="0" width="1428" height="682" style="fill:rgb(16.078431%,17.647059%,24.313725%);fill-opacity:1;stroke:none;"/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 434 124 L 448 124 L 448 155 L 434 155 Z M 434 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 0 0 L 854 0 L 854 31 L 0 31 Z M 0 0 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="0" y="26"/> + <use xlink:href="#glyph0-2" x="14" y="26"/> + <use xlink:href="#glyph0-3" x="28" y="26"/> + <use xlink:href="#glyph0-4" x="42" y="26"/> + <use xlink:href="#glyph0-5" x="56" y="26"/> + <use xlink:href="#glyph0-6" x="70" y="26"/> + <use xlink:href="#glyph0-7" x="84" y="26"/> + <use xlink:href="#glyph0-1" x="98" y="26"/> + <use xlink:href="#glyph0-2" x="112" y="26"/> + <use xlink:href="#glyph0-8" x="126" y="26"/> + <use xlink:href="#glyph0-9" x="140" y="26"/> + <use xlink:href="#glyph0-4" x="154" y="26"/> + <use xlink:href="#glyph0-10" x="168" y="26"/> + <use xlink:href="#glyph0-7" x="182" y="26"/> + <use xlink:href="#glyph0-1" x="196" y="26"/> + <use xlink:href="#glyph0-2" x="210" y="26"/> + <use xlink:href="#glyph0-11" x="224" y="26"/> + <use xlink:href="#glyph0-4" x="238" y="26"/> + <use xlink:href="#glyph0-6" x="252" y="26"/> + <use xlink:href="#glyph0-12" x="266" y="26"/> + <use xlink:href="#glyph0-7" x="280" y="26"/> + <use xlink:href="#glyph0-1" x="294" y="26"/> + <use xlink:href="#glyph0-2" x="308" y="26"/> + <use xlink:href="#glyph0-13" x="322" y="26"/> + <use xlink:href="#glyph0-4" x="336" y="26"/> + <use xlink:href="#glyph0-14" x="350" y="26"/> + <use xlink:href="#glyph0-9" x="364" y="26"/> + <use xlink:href="#glyph0-15" x="378" y="26"/> + <use xlink:href="#glyph0-12" x="392" y="26"/> + <use xlink:href="#glyph0-16" x="406" y="26"/> + <use xlink:href="#glyph0-7" x="420" y="26"/> + <use xlink:href="#glyph0-1" x="434" y="26"/> + <use xlink:href="#glyph0-2" x="448" y="26"/> + <use xlink:href="#glyph0-17" x="462" y="26"/> + <use xlink:href="#glyph0-6" x="476" y="26"/> + <use xlink:href="#glyph0-5" x="490" y="26"/> + <use xlink:href="#glyph0-18" x="504" y="26"/> + <use xlink:href="#glyph0-7" x="518" y="26"/> + <use xlink:href="#glyph0-1" x="532" y="26"/> + <use xlink:href="#glyph0-1" x="546" y="26"/> + <use xlink:href="#glyph0-1" x="560" y="26"/> + <use xlink:href="#glyph0-1" x="574" y="26"/> + <use xlink:href="#glyph0-1" x="588" y="26"/> + <use xlink:href="#glyph0-1" x="602" y="26"/> + <use xlink:href="#glyph0-1" x="616" y="26"/> + <use xlink:href="#glyph0-1" x="630" y="26"/> + <use xlink:href="#glyph0-1" x="644" y="26"/> + <use xlink:href="#glyph0-1" x="658" y="26"/> + <use xlink:href="#glyph0-1" x="672" y="26"/> + <use xlink:href="#glyph0-1" x="686" y="26"/> + <use xlink:href="#glyph0-1" x="700" y="26"/> + <use xlink:href="#glyph0-1" x="714" y="26"/> + <use xlink:href="#glyph0-1" x="728" y="26"/> + <use xlink:href="#glyph0-1" x="742" y="26"/> + <use xlink:href="#glyph0-1" x="756" y="26"/> + <use xlink:href="#glyph0-1" x="770" y="26"/> + <use xlink:href="#glyph0-1" x="784" y="26"/> + <use xlink:href="#glyph0-1" x="798" y="26"/> + <use xlink:href="#glyph0-1" x="812" y="26"/> + <use xlink:href="#glyph0-1" x="826" y="26"/> + <use xlink:href="#glyph0-1" x="840" y="26"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 854 0 L 1092 0 L 1092 31 L 854 31 Z M 854 0 "/> +<g style="fill:rgb(100%,72.156863%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="854" y="26"/> + <use xlink:href="#glyph0-15" x="868" y="26"/> + <use xlink:href="#glyph0-14" x="882" y="26"/> + <use xlink:href="#glyph0-16" x="896" y="26"/> + <use xlink:href="#glyph0-15" x="910" y="26"/> + <use xlink:href="#glyph0-5" x="924" y="26"/> + <use xlink:href="#glyph0-6" x="938" y="26"/> + <use xlink:href="#glyph0-1" x="952" y="26"/> + <use xlink:href="#glyph0-20" x="966" y="26"/> + <use xlink:href="#glyph0-6" x="980" y="26"/> + <use xlink:href="#glyph0-16" x="994" y="26"/> + <use xlink:href="#glyph0-10" x="1008" y="26"/> + <use xlink:href="#glyph0-1" x="1022" y="26"/> + <use xlink:href="#glyph0-21" x="1036" y="26"/> + <use xlink:href="#glyph0-15" x="1050" y="26"/> + <use xlink:href="#glyph0-9" x="1064" y="26"/> + <use xlink:href="#glyph0-6" x="1078" y="26"/> +</g> +<g style="fill:rgb(100%,72.156863%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="855" y="26"/> + <use xlink:href="#glyph0-15" x="869" y="26"/> + <use xlink:href="#glyph0-14" x="883" y="26"/> + <use xlink:href="#glyph0-16" x="897" y="26"/> + <use xlink:href="#glyph0-15" x="911" y="26"/> + <use xlink:href="#glyph0-5" x="925" y="26"/> + <use xlink:href="#glyph0-6" x="939" y="26"/> + <use xlink:href="#glyph0-1" x="953" y="26"/> + <use xlink:href="#glyph0-20" x="967" y="26"/> + <use xlink:href="#glyph0-6" x="981" y="26"/> + <use xlink:href="#glyph0-16" x="995" y="26"/> + <use xlink:href="#glyph0-10" x="1009" y="26"/> + <use xlink:href="#glyph0-1" x="1023" y="26"/> + <use xlink:href="#glyph0-21" x="1037" y="26"/> + <use xlink:href="#glyph0-15" x="1051" y="26"/> + <use xlink:href="#glyph0-9" x="1065" y="26"/> + <use xlink:href="#glyph0-6" x="1079" y="26"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1092 0 L 1120 0 L 1120 31 L 1092 31 Z M 1092 0 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1120 0 L 1134 0 L 1134 31 L 1120 31 Z M 1120 0 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1134 0 L 1302 0 L 1302 31 L 1134 31 Z M 1134 0 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-22" x="1134" y="26"/> + <use xlink:href="#glyph0-6" x="1148" y="26"/> + <use xlink:href="#glyph0-23" x="1162" y="26"/> + <use xlink:href="#glyph0-24" x="1176" y="26"/> + <use xlink:href="#glyph0-25" x="1190" y="26"/> + <use xlink:href="#glyph0-26" x="1204" y="26"/> + <use xlink:href="#glyph0-1" x="1218" y="26"/> + <use xlink:href="#glyph0-21" x="1232" y="26"/> + <use xlink:href="#glyph0-6" x="1246" y="26"/> + <use xlink:href="#glyph0-14" x="1260" y="26"/> + <use xlink:href="#glyph0-27" x="1274" y="26"/> + <use xlink:href="#glyph0-1" x="1288" y="26"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1302 0 L 1386 0 L 1386 31 L 1302 31 Z M 1302 0 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="1302" y="26"/> + <use xlink:href="#glyph0-10" x="1316" y="26"/> + <use xlink:href="#glyph0-24" x="1330" y="26"/> + <use xlink:href="#glyph0-5" x="1344" y="26"/> + <use xlink:href="#glyph0-28" x="1358" y="26"/> + <use xlink:href="#glyph0-18" x="1372" y="26"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="1303" y="26"/> + <use xlink:href="#glyph0-10" x="1317" y="26"/> + <use xlink:href="#glyph0-24" x="1331" y="26"/> + <use xlink:href="#glyph0-5" x="1345" y="26"/> + <use xlink:href="#glyph0-28" x="1359" y="26"/> + <use xlink:href="#glyph0-18" x="1373" y="26"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1386 0 L 1400 0 L 1400 31 L 1386 31 Z M 1386 0 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1400 0 L 1414 0 L 1414 31 L 1400 31 Z M 1400 0 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 0 L 1428 0 L 1428 31 L 1414 31 Z M 1414 0 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 0 31 L 14 31 L 14 62 L 0 62 Z M 0 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 14 31 L 112 31 L 112 62 L 14 62 Z M 14 31 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="14" y="57"/> + <use xlink:href="#glyph0-19" x="28" y="57"/> + <use xlink:href="#glyph0-5" x="42" y="57"/> + <use xlink:href="#glyph0-15" x="56" y="57"/> + <use xlink:href="#glyph0-25" x="70" y="57"/> + <use xlink:href="#glyph0-29" x="84" y="57"/> + <use xlink:href="#glyph0-1" x="98" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 112 31 L 126 31 L 126 62 L 112 62 Z M 112 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 126 31 L 364 31 L 364 62 L 126 62 Z M 126 31 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="126" y="57"/> + <use xlink:href="#glyph0-30" x="140" y="57"/> + <use xlink:href="#glyph0-12" x="154" y="57"/> + <use xlink:href="#glyph0-19" x="168" y="57"/> + <use xlink:href="#glyph0-15" x="182" y="57"/> + <use xlink:href="#glyph0-14" x="196" y="57"/> + <use xlink:href="#glyph0-16" x="210" y="57"/> + <use xlink:href="#glyph0-15" x="224" y="57"/> + <use xlink:href="#glyph0-5" x="238" y="57"/> + <use xlink:href="#glyph0-6" x="252" y="57"/> + <use xlink:href="#glyph0-1" x="266" y="57"/> + <use xlink:href="#glyph0-31" x="280" y="57"/> + <use xlink:href="#glyph0-6" x="294" y="57"/> + <use xlink:href="#glyph0-32" x="308" y="57"/> + <use xlink:href="#glyph0-27" x="322" y="57"/> + <use xlink:href="#glyph0-33" x="336" y="57"/> + <use xlink:href="#glyph0-1" x="350" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 364 31 L 378 31 L 378 62 L 364 62 Z M 364 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 378 31 L 560 31 L 560 62 L 378 62 Z M 378 31 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="378" y="57"/> + <use xlink:href="#glyph0-30" x="392" y="57"/> + <use xlink:href="#glyph0-34" x="406" y="57"/> + <use xlink:href="#glyph0-10" x="420" y="57"/> + <use xlink:href="#glyph0-26" x="434" y="57"/> + <use xlink:href="#glyph0-15" x="448" y="57"/> + <use xlink:href="#glyph0-14" x="462" y="57"/> + <use xlink:href="#glyph0-1" x="476" y="57"/> + <use xlink:href="#glyph0-35" x="490" y="57"/> + <use xlink:href="#glyph0-6" x="504" y="57"/> + <use xlink:href="#glyph0-18" x="518" y="57"/> + <use xlink:href="#glyph0-5" x="532" y="57"/> + <use xlink:href="#glyph0-1" x="546" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 560 31 L 574 31 L 574 62 L 560 62 Z M 560 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 574 31 L 714 31 L 714 62 L 574 62 Z M 574 31 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="574" y="57"/> + <use xlink:href="#glyph0-36" x="588" y="57"/> + <use xlink:href="#glyph0-5" x="602" y="57"/> + <use xlink:href="#glyph0-5" x="616" y="57"/> + <use xlink:href="#glyph0-1" x="630" y="57"/> + <use xlink:href="#glyph0-37" x="644" y="57"/> + <use xlink:href="#glyph0-15" x="658" y="57"/> + <use xlink:href="#glyph0-33" x="672" y="57"/> + <use xlink:href="#glyph0-16" x="686" y="57"/> + <use xlink:href="#glyph0-1" x="700" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 714 31 L 728 31 L 728 62 L 714 62 Z M 714 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 728 31 L 980 31 L 980 62 L 728 62 Z M 728 31 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="728" y="57"/> + <use xlink:href="#glyph0-3" x="742" y="57"/> + <use xlink:href="#glyph0-23" x="756" y="57"/> + <use xlink:href="#glyph0-29" x="770" y="57"/> + <use xlink:href="#glyph0-6" x="784" y="57"/> + <use xlink:href="#glyph0-1" x="798" y="57"/> + <use xlink:href="#glyph0-31" x="812" y="57"/> + <use xlink:href="#glyph0-6" x="826" y="57"/> + <use xlink:href="#glyph0-38" x="840" y="57"/> + <use xlink:href="#glyph0-4" x="854" y="57"/> + <use xlink:href="#glyph0-25" x="868" y="57"/> + <use xlink:href="#glyph0-6" x="882" y="57"/> + <use xlink:href="#glyph0-1" x="896" y="57"/> + <use xlink:href="#glyph0-37" x="910" y="57"/> + <use xlink:href="#glyph0-15" x="924" y="57"/> + <use xlink:href="#glyph0-33" x="938" y="57"/> + <use xlink:href="#glyph0-16" x="952" y="57"/> + <use xlink:href="#glyph0-1" x="966" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 980 31 L 994 31 L 994 62 L 980 62 Z M 980 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 994 31 L 1162 31 L 1162 62 L 994 62 Z M 994 31 "/> +<g style="fill:rgb(74.901961%,75.294118%,76.862745%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="994" y="57"/> + <use xlink:href="#glyph0-19" x="1008" y="57"/> + <use xlink:href="#glyph0-23" x="1022" y="57"/> + <use xlink:href="#glyph0-5" x="1036" y="57"/> + <use xlink:href="#glyph0-25" x="1050" y="57"/> + <use xlink:href="#glyph0-27" x="1064" y="57"/> + <use xlink:href="#glyph0-5" x="1078" y="57"/> + <use xlink:href="#glyph0-23" x="1092" y="57"/> + <use xlink:href="#glyph0-10" x="1106" y="57"/> + <use xlink:href="#glyph0-15" x="1120" y="57"/> + <use xlink:href="#glyph0-24" x="1134" y="57"/> + <use xlink:href="#glyph0-1" x="1148" y="57"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 1162 31 L 1414 31 L 1414 62 L 1162 62 Z M 1162 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 31 L 1428 31 L 1428 62 L 1414 62 Z M 1414 31 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 62 L 1400 62 L 1400 93 L 0 93 Z M 0 62 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 1400 62 L 1414 62 L 1414 93 L 1400 93 Z M 1400 62 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-39" x="1400" y="88"/> +</g> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-39" x="1401" y="88"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 62 L 1428 62 L 1428 93 L 1414 93 Z M 1414 62 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 93 L 140 93 L 140 124 L 0 124 Z M 0 93 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 93 L 1260 93 L 1260 124 L 140 124 Z M 140 93 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-40" x="140" y="119"/> + <use xlink:href="#glyph0-41" x="154" y="119"/> + <use xlink:href="#glyph0-41" x="168" y="119"/> + <use xlink:href="#glyph0-1" x="182" y="119"/> + <use xlink:href="#glyph0-21" x="196" y="119"/> + <use xlink:href="#glyph0-6" x="210" y="119"/> + <use xlink:href="#glyph0-14" x="224" y="119"/> + <use xlink:href="#glyph0-27" x="238" y="119"/> + <use xlink:href="#glyph0-1" x="252" y="119"/> + <use xlink:href="#glyph0-42" x="266" y="119"/> + <use xlink:href="#glyph0-10" x="280" y="119"/> + <use xlink:href="#glyph0-6" x="294" y="119"/> + <use xlink:href="#glyph0-43" x="308" y="119"/> + <use xlink:href="#glyph0-16" x="322" y="119"/> + <use xlink:href="#glyph0-1" x="336" y="119"/> + <use xlink:href="#glyph0-41" x="350" y="119"/> + <use xlink:href="#glyph0-41" x="364" y="119"/> + <use xlink:href="#glyph0-41" x="378" y="119"/> + <use xlink:href="#glyph0-41" x="392" y="119"/> + <use xlink:href="#glyph0-41" x="406" y="119"/> + <use xlink:href="#glyph0-41" x="420" y="119"/> + <use xlink:href="#glyph0-41" x="434" y="119"/> + <use xlink:href="#glyph0-41" x="448" y="119"/> + <use xlink:href="#glyph0-41" x="462" y="119"/> + <use xlink:href="#glyph0-41" x="476" y="119"/> + <use xlink:href="#glyph0-41" x="490" y="119"/> + <use xlink:href="#glyph0-41" x="504" y="119"/> + <use xlink:href="#glyph0-41" x="518" y="119"/> + <use xlink:href="#glyph0-41" x="532" y="119"/> + <use xlink:href="#glyph0-41" x="546" y="119"/> + <use xlink:href="#glyph0-41" x="560" y="119"/> + <use xlink:href="#glyph0-41" x="574" y="119"/> + <use xlink:href="#glyph0-41" x="588" y="119"/> + <use xlink:href="#glyph0-41" x="602" y="119"/> + <use xlink:href="#glyph0-41" x="616" y="119"/> + <use xlink:href="#glyph0-41" x="630" y="119"/> + <use xlink:href="#glyph0-41" x="644" y="119"/> + <use xlink:href="#glyph0-41" x="658" y="119"/> + <use xlink:href="#glyph0-41" x="672" y="119"/> + <use xlink:href="#glyph0-41" x="686" y="119"/> + <use xlink:href="#glyph0-41" x="700" y="119"/> + <use xlink:href="#glyph0-41" x="714" y="119"/> + <use xlink:href="#glyph0-41" x="728" y="119"/> + <use xlink:href="#glyph0-41" x="742" y="119"/> + <use xlink:href="#glyph0-41" x="756" y="119"/> + <use xlink:href="#glyph0-41" x="770" y="119"/> + <use xlink:href="#glyph0-41" x="784" y="119"/> + <use xlink:href="#glyph0-41" x="798" y="119"/> + <use xlink:href="#glyph0-41" x="812" y="119"/> + <use xlink:href="#glyph0-41" x="826" y="119"/> + <use xlink:href="#glyph0-41" x="840" y="119"/> + <use xlink:href="#glyph0-41" x="854" y="119"/> + <use xlink:href="#glyph0-41" x="868" y="119"/> + <use xlink:href="#glyph0-41" x="882" y="119"/> + <use xlink:href="#glyph0-41" x="896" y="119"/> + <use xlink:href="#glyph0-41" x="910" y="119"/> + <use xlink:href="#glyph0-41" x="924" y="119"/> + <use xlink:href="#glyph0-41" x="938" y="119"/> + <use xlink:href="#glyph0-41" x="952" y="119"/> + <use xlink:href="#glyph0-41" x="966" y="119"/> + <use xlink:href="#glyph0-41" x="980" y="119"/> + <use xlink:href="#glyph0-41" x="994" y="119"/> + <use xlink:href="#glyph0-41" x="1008" y="119"/> + <use xlink:href="#glyph0-41" x="1022" y="119"/> + <use xlink:href="#glyph0-41" x="1036" y="119"/> + <use xlink:href="#glyph0-41" x="1050" y="119"/> + <use xlink:href="#glyph0-41" x="1064" y="119"/> + <use xlink:href="#glyph0-41" x="1078" y="119"/> + <use xlink:href="#glyph0-41" x="1092" y="119"/> + <use xlink:href="#glyph0-41" x="1106" y="119"/> + <use xlink:href="#glyph0-41" x="1120" y="119"/> + <use xlink:href="#glyph0-41" x="1134" y="119"/> + <use xlink:href="#glyph0-41" x="1148" y="119"/> + <use xlink:href="#glyph0-41" x="1162" y="119"/> + <use xlink:href="#glyph0-41" x="1176" y="119"/> + <use xlink:href="#glyph0-41" x="1190" y="119"/> + <use xlink:href="#glyph0-41" x="1204" y="119"/> + <use xlink:href="#glyph0-41" x="1218" y="119"/> + <use xlink:href="#glyph0-41" x="1232" y="119"/> + <use xlink:href="#glyph0-44" x="1246" y="119"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 93 L 1400 93 L 1400 124 L 1260 124 Z M 1260 93 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 93 L 1414 93 L 1414 124 L 1400 124 Z M 1400 93 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 93 L 1428 93 L 1428 124 L 1414 124 Z M 1414 93 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 124 L 140 124 L 140 155 L 0 155 Z M 0 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 124 L 196 124 L 196 155 L 140 155 Z M 140 124 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="150"/> + <use xlink:href="#glyph0-1" x="154" y="150"/> + <use xlink:href="#glyph0-46" x="168" y="150"/> + <use xlink:href="#glyph0-1" x="182" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 196 124 L 854 124 L 854 155 L 196 155 Z M 196 124 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-9" x="196" y="150"/> + <use xlink:href="#glyph0-6" x="210" y="150"/> + <use xlink:href="#glyph0-38" x="224" y="150"/> + <use xlink:href="#glyph0-4" x="238" y="150"/> + <use xlink:href="#glyph0-25" x="252" y="150"/> + <use xlink:href="#glyph0-6" x="266" y="150"/> + <use xlink:href="#glyph0-1" x="280" y="150"/> + <use xlink:href="#glyph0-5" x="294" y="150"/> + <use xlink:href="#glyph0-15" x="308" y="150"/> + <use xlink:href="#glyph0-33" x="322" y="150"/> + <use xlink:href="#glyph0-1" x="336" y="150"/> + <use xlink:href="#glyph0-12" x="350" y="150"/> + <use xlink:href="#glyph0-4" x="364" y="150"/> + <use xlink:href="#glyph0-14" x="378" y="150"/> + <use xlink:href="#glyph0-9" x="392" y="150"/> + <use xlink:href="#glyph0-15" x="406" y="150"/> + <use xlink:href="#glyph0-12" x="420" y="150"/> + <use xlink:href="#glyph0-1" x="434" y="150"/> + <use xlink:href="#glyph0-1" x="448" y="150"/> + <use xlink:href="#glyph0-1" x="462" y="150"/> + <use xlink:href="#glyph0-1" x="476" y="150"/> + <use xlink:href="#glyph0-1" x="490" y="150"/> + <use xlink:href="#glyph0-1" x="504" y="150"/> + <use xlink:href="#glyph0-1" x="518" y="150"/> + <use xlink:href="#glyph0-1" x="532" y="150"/> + <use xlink:href="#glyph0-1" x="546" y="150"/> + <use xlink:href="#glyph0-1" x="560" y="150"/> + <use xlink:href="#glyph0-1" x="574" y="150"/> + <use xlink:href="#glyph0-1" x="588" y="150"/> + <use xlink:href="#glyph0-1" x="602" y="150"/> + <use xlink:href="#glyph0-1" x="616" y="150"/> + <use xlink:href="#glyph0-1" x="630" y="150"/> + <use xlink:href="#glyph0-1" x="644" y="150"/> + <use xlink:href="#glyph0-1" x="658" y="150"/> + <use xlink:href="#glyph0-1" x="672" y="150"/> + <use xlink:href="#glyph0-1" x="686" y="150"/> + <use xlink:href="#glyph0-1" x="700" y="150"/> + <use xlink:href="#glyph0-1" x="714" y="150"/> + <use xlink:href="#glyph0-1" x="728" y="150"/> + <use xlink:href="#glyph0-1" x="742" y="150"/> + <use xlink:href="#glyph0-1" x="756" y="150"/> + <use xlink:href="#glyph0-1" x="770" y="150"/> + <use xlink:href="#glyph0-1" x="784" y="150"/> + <use xlink:href="#glyph0-1" x="798" y="150"/> + <use xlink:href="#glyph0-1" x="812" y="150"/> + <use xlink:href="#glyph0-1" x="826" y="150"/> + <use xlink:href="#glyph0-1" x="840" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 854 124 L 868 124 L 868 155 L 854 155 Z M 854 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 868 124 L 966 124 L 966 155 L 868 155 Z M 868 124 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="868" y="150"/> + <use xlink:href="#glyph0-23" x="882" y="150"/> + <use xlink:href="#glyph0-14" x="896" y="150"/> + <use xlink:href="#glyph0-25" x="910" y="150"/> + <use xlink:href="#glyph0-6" x="924" y="150"/> + <use xlink:href="#glyph0-5" x="938" y="150"/> + <use xlink:href="#glyph0-1" x="952" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 966 124 L 1050 124 L 1050 155 L 966 155 Z M 966 124 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="966" y="150"/> + <use xlink:href="#glyph0-10" x="980" y="150"/> + <use xlink:href="#glyph0-24" x="994" y="150"/> + <use xlink:href="#glyph0-5" x="1008" y="150"/> + <use xlink:href="#glyph0-28" x="1022" y="150"/> + <use xlink:href="#glyph0-25" x="1036" y="150"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="967" y="150"/> + <use xlink:href="#glyph0-10" x="981" y="150"/> + <use xlink:href="#glyph0-24" x="995" y="150"/> + <use xlink:href="#glyph0-5" x="1009" y="150"/> + <use xlink:href="#glyph0-28" x="1023" y="150"/> + <use xlink:href="#glyph0-25" x="1037" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1050 124 L 1064 124 L 1064 155 L 1050 155 Z M 1050 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1064 124 L 1078 124 L 1078 155 L 1064 155 Z M 1064 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1078 124 L 1092 124 L 1092 155 L 1078 155 Z M 1078 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1092 124 L 1148 124 L 1148 155 L 1092 155 Z M 1092 124 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-35" x="1092" y="150"/> + <use xlink:href="#glyph0-27" x="1106" y="150"/> + <use xlink:href="#glyph0-14" x="1120" y="150"/> + <use xlink:href="#glyph0-1" x="1134" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1148 124 L 1218 124 L 1218 155 L 1148 155 Z M 1148 124 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-8" x="1148" y="150"/> + <use xlink:href="#glyph0-14" x="1162" y="150"/> + <use xlink:href="#glyph0-10" x="1176" y="150"/> + <use xlink:href="#glyph0-6" x="1190" y="150"/> + <use xlink:href="#glyph0-24" x="1204" y="150"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-8" x="1149" y="150"/> + <use xlink:href="#glyph0-14" x="1163" y="150"/> + <use xlink:href="#glyph0-10" x="1177" y="150"/> + <use xlink:href="#glyph0-6" x="1191" y="150"/> + <use xlink:href="#glyph0-24" x="1205" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1218 124 L 1232 124 L 1232 155 L 1218 155 Z M 1218 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 124 L 1260 124 L 1260 155 L 1232 155 Z M 1232 124 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="150"/> + <use xlink:href="#glyph0-45" x="1246" y="150"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 124 L 1400 124 L 1400 155 L 1260 155 Z M 1260 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 124 L 1414 124 L 1414 155 L 1400 155 Z M 1400 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 124 L 1428 124 L 1428 155 L 1414 155 Z M 1414 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 155 L 140 155 L 140 186 L 0 186 Z M 0 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 155 L 168 155 L 168 186 L 140 186 Z M 140 155 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="181"/> + <use xlink:href="#glyph0-1" x="154" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 168 155 L 182 155 L 182 186 L 168 186 Z M 168 155 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 182 155 L 266 155 L 266 186 L 182 186 Z M 182 155 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="181"/> + <use xlink:href="#glyph0-4" x="196" y="181"/> + <use xlink:href="#glyph0-14" x="210" y="181"/> + <use xlink:href="#glyph0-9" x="224" y="181"/> + <use xlink:href="#glyph0-15" x="238" y="181"/> + <use xlink:href="#glyph0-12" x="252" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 266 155 L 448 155 L 448 186 L 266 186 Z M 266 155 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="181"/> + <use xlink:href="#glyph0-7" x="280" y="181"/> + <use xlink:href="#glyph0-1" x="294" y="181"/> + <use xlink:href="#glyph0-46" x="308" y="181"/> + <use xlink:href="#glyph0-1" x="322" y="181"/> + <use xlink:href="#glyph0-47" x="336" y="181"/> + <use xlink:href="#glyph0-48" x="350" y="181"/> + <use xlink:href="#glyph0-1" x="364" y="181"/> + <use xlink:href="#glyph0-3" x="378" y="181"/> + <use xlink:href="#glyph0-23" x="392" y="181"/> + <use xlink:href="#glyph0-29" x="406" y="181"/> + <use xlink:href="#glyph0-6" x="420" y="181"/> + <use xlink:href="#glyph0-1" x="434" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 448 155 L 532 155 L 532 186 L 448 186 Z M 448 155 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="181"/> + <use xlink:href="#glyph0-6" x="462" y="181"/> + <use xlink:href="#glyph0-38" x="476" y="181"/> + <use xlink:href="#glyph0-4" x="490" y="181"/> + <use xlink:href="#glyph0-25" x="504" y="181"/> + <use xlink:href="#glyph0-6" x="518" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 532 155 L 546 155 L 546 186 L 532 186 Z M 532 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 546 155 L 588 155 L 588 186 L 546 186 Z M 546 155 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="181"/> + <use xlink:href="#glyph0-15" x="560" y="181"/> + <use xlink:href="#glyph0-33" x="574" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 588 155 L 840 155 L 840 186 L 588 186 Z M 588 155 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="181"/> + <use xlink:href="#glyph0-1" x="602" y="181"/> + <use xlink:href="#glyph0-46" x="616" y="181"/> + <use xlink:href="#glyph0-1" x="630" y="181"/> + <use xlink:href="#glyph0-2" x="644" y="181"/> + <use xlink:href="#glyph0-49" x="658" y="181"/> + <use xlink:href="#glyph0-7" x="672" y="181"/> + <use xlink:href="#glyph0-1" x="686" y="181"/> + <use xlink:href="#glyph0-22" x="700" y="181"/> + <use xlink:href="#glyph0-26" x="714" y="181"/> + <use xlink:href="#glyph0-15" x="728" y="181"/> + <use xlink:href="#glyph0-12" x="742" y="181"/> + <use xlink:href="#glyph0-50" x="756" y="181"/> + <use xlink:href="#glyph0-17" x="770" y="181"/> + <use xlink:href="#glyph0-4" x="784" y="181"/> + <use xlink:href="#glyph0-9" x="798" y="181"/> + <use xlink:href="#glyph0-6" x="812" y="181"/> + <use xlink:href="#glyph0-1" x="826" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 840 155 L 924 155 L 924 186 L 840 186 Z M 840 155 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="840" y="181"/> + <use xlink:href="#glyph0-4" x="854" y="181"/> + <use xlink:href="#glyph0-14" x="868" y="181"/> + <use xlink:href="#glyph0-9" x="882" y="181"/> + <use xlink:href="#glyph0-15" x="896" y="181"/> + <use xlink:href="#glyph0-12" x="910" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,30.588235%,30.588235%);fill-opacity:1;" d="M 924 155 L 1232 155 L 1232 186 L 924 186 Z M 924 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 155 L 1260 155 L 1260 186 L 1232 186 Z M 1232 155 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="181"/> + <use xlink:href="#glyph0-45" x="1246" y="181"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 155 L 1400 155 L 1400 186 L 1260 186 Z M 1260 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 155 L 1414 155 L 1414 186 L 1400 186 Z M 1400 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 155 L 1428 155 L 1428 186 L 1414 186 Z M 1414 155 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 186 L 140 186 L 140 217 L 0 217 Z M 0 186 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 186 L 168 186 L 168 217 L 140 217 Z M 140 186 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="212"/> + <use xlink:href="#glyph0-1" x="154" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 186 L 182 186 L 182 217 L 168 217 Z M 168 186 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 186 L 266 186 L 266 217 L 182 217 Z M 182 186 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="212"/> + <use xlink:href="#glyph0-4" x="196" y="212"/> + <use xlink:href="#glyph0-14" x="210" y="212"/> + <use xlink:href="#glyph0-9" x="224" y="212"/> + <use xlink:href="#glyph0-15" x="238" y="212"/> + <use xlink:href="#glyph0-12" x="252" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 186 L 448 186 L 448 217 L 266 217 Z M 266 186 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="212"/> + <use xlink:href="#glyph0-7" x="280" y="212"/> + <use xlink:href="#glyph0-1" x="294" y="212"/> + <use xlink:href="#glyph0-46" x="308" y="212"/> + <use xlink:href="#glyph0-1" x="322" y="212"/> + <use xlink:href="#glyph0-47" x="336" y="212"/> + <use xlink:href="#glyph0-48" x="350" y="212"/> + <use xlink:href="#glyph0-1" x="364" y="212"/> + <use xlink:href="#glyph0-3" x="378" y="212"/> + <use xlink:href="#glyph0-23" x="392" y="212"/> + <use xlink:href="#glyph0-29" x="406" y="212"/> + <use xlink:href="#glyph0-6" x="420" y="212"/> + <use xlink:href="#glyph0-1" x="434" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 186 L 532 186 L 532 217 L 448 217 Z M 448 186 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="212"/> + <use xlink:href="#glyph0-6" x="462" y="212"/> + <use xlink:href="#glyph0-38" x="476" y="212"/> + <use xlink:href="#glyph0-4" x="490" y="212"/> + <use xlink:href="#glyph0-25" x="504" y="212"/> + <use xlink:href="#glyph0-6" x="518" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 186 L 546 186 L 546 217 L 532 217 Z M 532 186 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 186 L 588 186 L 588 217 L 546 217 Z M 546 186 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="212"/> + <use xlink:href="#glyph0-15" x="560" y="212"/> + <use xlink:href="#glyph0-33" x="574" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 186 L 1232 186 L 1232 217 L 588 217 Z M 588 186 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="212"/> + <use xlink:href="#glyph0-1" x="602" y="212"/> + <use xlink:href="#glyph0-46" x="616" y="212"/> + <use xlink:href="#glyph0-1" x="630" y="212"/> + <use xlink:href="#glyph0-22" x="644" y="212"/> + <use xlink:href="#glyph0-23" x="658" y="212"/> + <use xlink:href="#glyph0-38" x="672" y="212"/> + <use xlink:href="#glyph0-6" x="686" y="212"/> + <use xlink:href="#glyph0-50" x="700" y="212"/> + <use xlink:href="#glyph0-8" x="714" y="212"/> + <use xlink:href="#glyph0-51" x="728" y="212"/> + <use xlink:href="#glyph0-18" x="742" y="212"/> + <use xlink:href="#glyph0-15" x="756" y="212"/> + <use xlink:href="#glyph0-24" x="770" y="212"/> + <use xlink:href="#glyph0-10" x="784" y="212"/> + <use xlink:href="#glyph0-1" x="798" y="212"/> + <use xlink:href="#glyph0-23" x="812" y="212"/> + <use xlink:href="#glyph0-1" x="826" y="212"/> + <use xlink:href="#glyph0-25" x="840" y="212"/> + <use xlink:href="#glyph0-15" x="854" y="212"/> + <use xlink:href="#glyph0-18" x="868" y="212"/> + <use xlink:href="#glyph0-34" x="882" y="212"/> + <use xlink:href="#glyph0-1" x="896" y="212"/> + <use xlink:href="#glyph0-1" x="910" y="212"/> + <use xlink:href="#glyph0-1" x="924" y="212"/> + <use xlink:href="#glyph0-1" x="938" y="212"/> + <use xlink:href="#glyph0-1" x="952" y="212"/> + <use xlink:href="#glyph0-1" x="966" y="212"/> + <use xlink:href="#glyph0-1" x="980" y="212"/> + <use xlink:href="#glyph0-1" x="994" y="212"/> + <use xlink:href="#glyph0-1" x="1008" y="212"/> + <use xlink:href="#glyph0-1" x="1022" y="212"/> + <use xlink:href="#glyph0-1" x="1036" y="212"/> + <use xlink:href="#glyph0-1" x="1050" y="212"/> + <use xlink:href="#glyph0-1" x="1064" y="212"/> + <use xlink:href="#glyph0-1" x="1078" y="212"/> + <use xlink:href="#glyph0-1" x="1092" y="212"/> + <use xlink:href="#glyph0-1" x="1106" y="212"/> + <use xlink:href="#glyph0-1" x="1120" y="212"/> + <use xlink:href="#glyph0-1" x="1134" y="212"/> + <use xlink:href="#glyph0-1" x="1148" y="212"/> + <use xlink:href="#glyph0-1" x="1162" y="212"/> + <use xlink:href="#glyph0-1" x="1176" y="212"/> + <use xlink:href="#glyph0-1" x="1190" y="212"/> + <use xlink:href="#glyph0-1" x="1204" y="212"/> + <use xlink:href="#glyph0-1" x="1218" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 186 L 1260 186 L 1260 217 L 1232 217 Z M 1232 186 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="212"/> + <use xlink:href="#glyph0-45" x="1246" y="212"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 186 L 1400 186 L 1400 217 L 1260 217 Z M 1260 186 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 186 L 1414 186 L 1414 217 L 1400 217 Z M 1400 186 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 186 L 1428 186 L 1428 217 L 1414 217 Z M 1414 186 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 217 L 140 217 L 140 248 L 0 248 Z M 0 217 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 217 L 168 217 L 168 248 L 140 248 Z M 140 217 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="243"/> + <use xlink:href="#glyph0-1" x="154" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 217 L 182 217 L 182 248 L 168 248 Z M 168 217 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 217 L 266 217 L 266 248 L 182 248 Z M 182 217 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="243"/> + <use xlink:href="#glyph0-4" x="196" y="243"/> + <use xlink:href="#glyph0-14" x="210" y="243"/> + <use xlink:href="#glyph0-9" x="224" y="243"/> + <use xlink:href="#glyph0-15" x="238" y="243"/> + <use xlink:href="#glyph0-12" x="252" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 217 L 448 217 L 448 248 L 266 248 Z M 266 217 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="243"/> + <use xlink:href="#glyph0-7" x="280" y="243"/> + <use xlink:href="#glyph0-1" x="294" y="243"/> + <use xlink:href="#glyph0-46" x="308" y="243"/> + <use xlink:href="#glyph0-1" x="322" y="243"/> + <use xlink:href="#glyph0-47" x="336" y="243"/> + <use xlink:href="#glyph0-48" x="350" y="243"/> + <use xlink:href="#glyph0-1" x="364" y="243"/> + <use xlink:href="#glyph0-3" x="378" y="243"/> + <use xlink:href="#glyph0-23" x="392" y="243"/> + <use xlink:href="#glyph0-29" x="406" y="243"/> + <use xlink:href="#glyph0-6" x="420" y="243"/> + <use xlink:href="#glyph0-1" x="434" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 217 L 532 217 L 532 248 L 448 248 Z M 448 217 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="243"/> + <use xlink:href="#glyph0-6" x="462" y="243"/> + <use xlink:href="#glyph0-38" x="476" y="243"/> + <use xlink:href="#glyph0-4" x="490" y="243"/> + <use xlink:href="#glyph0-25" x="504" y="243"/> + <use xlink:href="#glyph0-6" x="518" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 217 L 546 217 L 546 248 L 532 248 Z M 532 217 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 217 L 588 217 L 588 248 L 546 248 Z M 546 217 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="243"/> + <use xlink:href="#glyph0-15" x="560" y="243"/> + <use xlink:href="#glyph0-33" x="574" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 217 L 1232 217 L 1232 248 L 588 248 Z M 588 217 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="243"/> + <use xlink:href="#glyph0-1" x="602" y="243"/> + <use xlink:href="#glyph0-46" x="616" y="243"/> + <use xlink:href="#glyph0-1" x="630" y="243"/> + <use xlink:href="#glyph0-2" x="644" y="243"/> + <use xlink:href="#glyph0-1" x="658" y="243"/> + <use xlink:href="#glyph0-7" x="672" y="243"/> + <use xlink:href="#glyph0-1" x="686" y="243"/> + <use xlink:href="#glyph0-37" x="700" y="243"/> + <use xlink:href="#glyph0-4" x="714" y="243"/> + <use xlink:href="#glyph0-14" x="728" y="243"/> + <use xlink:href="#glyph0-6" x="742" y="243"/> + <use xlink:href="#glyph0-1" x="756" y="243"/> + <use xlink:href="#glyph0-12" x="770" y="243"/> + <use xlink:href="#glyph0-24" x="784" y="243"/> + <use xlink:href="#glyph0-23" x="798" y="243"/> + <use xlink:href="#glyph0-18" x="812" y="243"/> + <use xlink:href="#glyph0-18" x="826" y="243"/> + <use xlink:href="#glyph0-4" x="840" y="243"/> + <use xlink:href="#glyph0-14" x="854" y="243"/> + <use xlink:href="#glyph0-33" x="868" y="243"/> + <use xlink:href="#glyph0-1" x="882" y="243"/> + <use xlink:href="#glyph0-1" x="896" y="243"/> + <use xlink:href="#glyph0-1" x="910" y="243"/> + <use xlink:href="#glyph0-1" x="924" y="243"/> + <use xlink:href="#glyph0-1" x="938" y="243"/> + <use xlink:href="#glyph0-1" x="952" y="243"/> + <use xlink:href="#glyph0-1" x="966" y="243"/> + <use xlink:href="#glyph0-1" x="980" y="243"/> + <use xlink:href="#glyph0-1" x="994" y="243"/> + <use xlink:href="#glyph0-1" x="1008" y="243"/> + <use xlink:href="#glyph0-1" x="1022" y="243"/> + <use xlink:href="#glyph0-1" x="1036" y="243"/> + <use xlink:href="#glyph0-1" x="1050" y="243"/> + <use xlink:href="#glyph0-1" x="1064" y="243"/> + <use xlink:href="#glyph0-1" x="1078" y="243"/> + <use xlink:href="#glyph0-1" x="1092" y="243"/> + <use xlink:href="#glyph0-1" x="1106" y="243"/> + <use xlink:href="#glyph0-1" x="1120" y="243"/> + <use xlink:href="#glyph0-1" x="1134" y="243"/> + <use xlink:href="#glyph0-1" x="1148" y="243"/> + <use xlink:href="#glyph0-1" x="1162" y="243"/> + <use xlink:href="#glyph0-1" x="1176" y="243"/> + <use xlink:href="#glyph0-1" x="1190" y="243"/> + <use xlink:href="#glyph0-1" x="1204" y="243"/> + <use xlink:href="#glyph0-1" x="1218" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 217 L 1260 217 L 1260 248 L 1232 248 Z M 1232 217 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="243"/> + <use xlink:href="#glyph0-45" x="1246" y="243"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 217 L 1400 217 L 1400 248 L 1260 248 Z M 1260 217 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 217 L 1414 217 L 1414 248 L 1400 248 Z M 1400 217 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 217 L 1428 217 L 1428 248 L 1414 248 Z M 1414 217 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 248 L 140 248 L 140 279 L 0 279 Z M 0 248 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 248 L 168 248 L 168 279 L 140 279 Z M 140 248 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="274"/> + <use xlink:href="#glyph0-1" x="154" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 248 L 182 248 L 182 279 L 168 279 Z M 168 248 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 248 L 266 248 L 266 279 L 182 279 Z M 182 248 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="274"/> + <use xlink:href="#glyph0-4" x="196" y="274"/> + <use xlink:href="#glyph0-14" x="210" y="274"/> + <use xlink:href="#glyph0-9" x="224" y="274"/> + <use xlink:href="#glyph0-15" x="238" y="274"/> + <use xlink:href="#glyph0-12" x="252" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 248 L 448 248 L 448 279 L 266 279 Z M 266 248 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="274"/> + <use xlink:href="#glyph0-7" x="280" y="274"/> + <use xlink:href="#glyph0-1" x="294" y="274"/> + <use xlink:href="#glyph0-46" x="308" y="274"/> + <use xlink:href="#glyph0-1" x="322" y="274"/> + <use xlink:href="#glyph0-47" x="336" y="274"/> + <use xlink:href="#glyph0-48" x="350" y="274"/> + <use xlink:href="#glyph0-1" x="364" y="274"/> + <use xlink:href="#glyph0-3" x="378" y="274"/> + <use xlink:href="#glyph0-23" x="392" y="274"/> + <use xlink:href="#glyph0-29" x="406" y="274"/> + <use xlink:href="#glyph0-6" x="420" y="274"/> + <use xlink:href="#glyph0-1" x="434" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 248 L 532 248 L 532 279 L 448 279 Z M 448 248 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="274"/> + <use xlink:href="#glyph0-6" x="462" y="274"/> + <use xlink:href="#glyph0-38" x="476" y="274"/> + <use xlink:href="#glyph0-4" x="490" y="274"/> + <use xlink:href="#glyph0-25" x="504" y="274"/> + <use xlink:href="#glyph0-6" x="518" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 248 L 546 248 L 546 279 L 532 279 Z M 532 248 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 248 L 588 248 L 588 279 L 546 279 Z M 546 248 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="274"/> + <use xlink:href="#glyph0-15" x="560" y="274"/> + <use xlink:href="#glyph0-33" x="574" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 248 L 1232 248 L 1232 279 L 588 279 Z M 588 248 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="274"/> + <use xlink:href="#glyph0-1" x="602" y="274"/> + <use xlink:href="#glyph0-46" x="616" y="274"/> + <use xlink:href="#glyph0-1" x="630" y="274"/> + <use xlink:href="#glyph0-2" x="644" y="274"/> + <use xlink:href="#glyph0-49" x="658" y="274"/> + <use xlink:href="#glyph0-7" x="672" y="274"/> + <use xlink:href="#glyph0-1" x="686" y="274"/> + <use xlink:href="#glyph0-20" x="700" y="274"/> + <use xlink:href="#glyph0-23" x="714" y="274"/> + <use xlink:href="#glyph0-32" x="728" y="274"/> + <use xlink:href="#glyph0-5" x="742" y="274"/> + <use xlink:href="#glyph0-6" x="756" y="274"/> + <use xlink:href="#glyph0-1" x="770" y="274"/> + <use xlink:href="#glyph0-38" x="784" y="274"/> + <use xlink:href="#glyph0-4" x="798" y="274"/> + <use xlink:href="#glyph0-6" x="812" y="274"/> + <use xlink:href="#glyph0-12" x="826" y="274"/> + <use xlink:href="#glyph0-1" x="840" y="274"/> + <use xlink:href="#glyph0-1" x="854" y="274"/> + <use xlink:href="#glyph0-1" x="868" y="274"/> + <use xlink:href="#glyph0-1" x="882" y="274"/> + <use xlink:href="#glyph0-1" x="896" y="274"/> + <use xlink:href="#glyph0-1" x="910" y="274"/> + <use xlink:href="#glyph0-1" x="924" y="274"/> + <use xlink:href="#glyph0-1" x="938" y="274"/> + <use xlink:href="#glyph0-1" x="952" y="274"/> + <use xlink:href="#glyph0-1" x="966" y="274"/> + <use xlink:href="#glyph0-1" x="980" y="274"/> + <use xlink:href="#glyph0-1" x="994" y="274"/> + <use xlink:href="#glyph0-1" x="1008" y="274"/> + <use xlink:href="#glyph0-1" x="1022" y="274"/> + <use xlink:href="#glyph0-1" x="1036" y="274"/> + <use xlink:href="#glyph0-1" x="1050" y="274"/> + <use xlink:href="#glyph0-1" x="1064" y="274"/> + <use xlink:href="#glyph0-1" x="1078" y="274"/> + <use xlink:href="#glyph0-1" x="1092" y="274"/> + <use xlink:href="#glyph0-1" x="1106" y="274"/> + <use xlink:href="#glyph0-1" x="1120" y="274"/> + <use xlink:href="#glyph0-1" x="1134" y="274"/> + <use xlink:href="#glyph0-1" x="1148" y="274"/> + <use xlink:href="#glyph0-1" x="1162" y="274"/> + <use xlink:href="#glyph0-1" x="1176" y="274"/> + <use xlink:href="#glyph0-1" x="1190" y="274"/> + <use xlink:href="#glyph0-1" x="1204" y="274"/> + <use xlink:href="#glyph0-1" x="1218" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 248 L 1260 248 L 1260 279 L 1232 279 Z M 1232 248 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="274"/> + <use xlink:href="#glyph0-45" x="1246" y="274"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 248 L 1400 248 L 1400 279 L 1260 279 Z M 1260 248 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 248 L 1414 248 L 1414 279 L 1400 279 Z M 1400 248 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 248 L 1428 248 L 1428 279 L 1414 279 Z M 1414 248 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 279 L 140 279 L 140 310 L 0 310 Z M 0 279 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 279 L 168 279 L 168 310 L 140 310 Z M 140 279 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="305"/> + <use xlink:href="#glyph0-1" x="154" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 279 L 182 279 L 182 310 L 168 310 Z M 168 279 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 279 L 266 279 L 266 310 L 182 310 Z M 182 279 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="305"/> + <use xlink:href="#glyph0-4" x="196" y="305"/> + <use xlink:href="#glyph0-14" x="210" y="305"/> + <use xlink:href="#glyph0-9" x="224" y="305"/> + <use xlink:href="#glyph0-15" x="238" y="305"/> + <use xlink:href="#glyph0-12" x="252" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 279 L 448 279 L 448 310 L 266 310 Z M 266 279 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="305"/> + <use xlink:href="#glyph0-7" x="280" y="305"/> + <use xlink:href="#glyph0-1" x="294" y="305"/> + <use xlink:href="#glyph0-46" x="308" y="305"/> + <use xlink:href="#glyph0-1" x="322" y="305"/> + <use xlink:href="#glyph0-47" x="336" y="305"/> + <use xlink:href="#glyph0-48" x="350" y="305"/> + <use xlink:href="#glyph0-1" x="364" y="305"/> + <use xlink:href="#glyph0-3" x="378" y="305"/> + <use xlink:href="#glyph0-23" x="392" y="305"/> + <use xlink:href="#glyph0-29" x="406" y="305"/> + <use xlink:href="#glyph0-6" x="420" y="305"/> + <use xlink:href="#glyph0-1" x="434" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 279 L 532 279 L 532 310 L 448 310 Z M 448 279 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="305"/> + <use xlink:href="#glyph0-6" x="462" y="305"/> + <use xlink:href="#glyph0-38" x="476" y="305"/> + <use xlink:href="#glyph0-4" x="490" y="305"/> + <use xlink:href="#glyph0-25" x="504" y="305"/> + <use xlink:href="#glyph0-6" x="518" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 279 L 546 279 L 546 310 L 532 310 Z M 532 279 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 279 L 588 279 L 588 310 L 546 310 Z M 546 279 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="305"/> + <use xlink:href="#glyph0-15" x="560" y="305"/> + <use xlink:href="#glyph0-33" x="574" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 279 L 1232 279 L 1232 310 L 588 310 Z M 588 279 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="305"/> + <use xlink:href="#glyph0-1" x="602" y="305"/> + <use xlink:href="#glyph0-46" x="616" y="305"/> + <use xlink:href="#glyph0-1" x="630" y="305"/> + <use xlink:href="#glyph0-2" x="644" y="305"/> + <use xlink:href="#glyph0-49" x="658" y="305"/> + <use xlink:href="#glyph0-7" x="672" y="305"/> + <use xlink:href="#glyph0-1" x="686" y="305"/> + <use xlink:href="#glyph0-3" x="700" y="305"/> + <use xlink:href="#glyph0-15" x="714" y="305"/> + <use xlink:href="#glyph0-5" x="728" y="305"/> + <use xlink:href="#glyph0-5" x="742" y="305"/> + <use xlink:href="#glyph0-15" x="756" y="305"/> + <use xlink:href="#glyph0-12" x="770" y="305"/> + <use xlink:href="#glyph0-1" x="784" y="305"/> + <use xlink:href="#glyph0-1" x="798" y="305"/> + <use xlink:href="#glyph0-1" x="812" y="305"/> + <use xlink:href="#glyph0-1" x="826" y="305"/> + <use xlink:href="#glyph0-1" x="840" y="305"/> + <use xlink:href="#glyph0-1" x="854" y="305"/> + <use xlink:href="#glyph0-1" x="868" y="305"/> + <use xlink:href="#glyph0-1" x="882" y="305"/> + <use xlink:href="#glyph0-1" x="896" y="305"/> + <use xlink:href="#glyph0-1" x="910" y="305"/> + <use xlink:href="#glyph0-1" x="924" y="305"/> + <use xlink:href="#glyph0-1" x="938" y="305"/> + <use xlink:href="#glyph0-1" x="952" y="305"/> + <use xlink:href="#glyph0-1" x="966" y="305"/> + <use xlink:href="#glyph0-1" x="980" y="305"/> + <use xlink:href="#glyph0-1" x="994" y="305"/> + <use xlink:href="#glyph0-1" x="1008" y="305"/> + <use xlink:href="#glyph0-1" x="1022" y="305"/> + <use xlink:href="#glyph0-1" x="1036" y="305"/> + <use xlink:href="#glyph0-1" x="1050" y="305"/> + <use xlink:href="#glyph0-1" x="1064" y="305"/> + <use xlink:href="#glyph0-1" x="1078" y="305"/> + <use xlink:href="#glyph0-1" x="1092" y="305"/> + <use xlink:href="#glyph0-1" x="1106" y="305"/> + <use xlink:href="#glyph0-1" x="1120" y="305"/> + <use xlink:href="#glyph0-1" x="1134" y="305"/> + <use xlink:href="#glyph0-1" x="1148" y="305"/> + <use xlink:href="#glyph0-1" x="1162" y="305"/> + <use xlink:href="#glyph0-1" x="1176" y="305"/> + <use xlink:href="#glyph0-1" x="1190" y="305"/> + <use xlink:href="#glyph0-1" x="1204" y="305"/> + <use xlink:href="#glyph0-1" x="1218" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 279 L 1260 279 L 1260 310 L 1232 310 Z M 1232 279 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="305"/> + <use xlink:href="#glyph0-45" x="1246" y="305"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 279 L 1400 279 L 1400 310 L 1260 310 Z M 1260 279 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;" d="M 1400 279 L 1414 279 L 1414 310 L 1400 310 Z M 1400 279 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 279 L 1428 279 L 1428 310 L 1414 310 Z M 1414 279 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 310 L 140 310 L 140 341 L 0 341 Z M 0 310 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 310 L 168 310 L 168 341 L 140 341 Z M 140 310 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="336"/> + <use xlink:href="#glyph0-1" x="154" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 310 L 182 310 L 182 341 L 168 341 Z M 168 310 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 310 L 266 310 L 266 341 L 182 341 Z M 182 310 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="336"/> + <use xlink:href="#glyph0-4" x="196" y="336"/> + <use xlink:href="#glyph0-14" x="210" y="336"/> + <use xlink:href="#glyph0-9" x="224" y="336"/> + <use xlink:href="#glyph0-15" x="238" y="336"/> + <use xlink:href="#glyph0-12" x="252" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 310 L 448 310 L 448 341 L 266 341 Z M 266 310 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="336"/> + <use xlink:href="#glyph0-7" x="280" y="336"/> + <use xlink:href="#glyph0-1" x="294" y="336"/> + <use xlink:href="#glyph0-46" x="308" y="336"/> + <use xlink:href="#glyph0-1" x="322" y="336"/> + <use xlink:href="#glyph0-47" x="336" y="336"/> + <use xlink:href="#glyph0-48" x="350" y="336"/> + <use xlink:href="#glyph0-1" x="364" y="336"/> + <use xlink:href="#glyph0-3" x="378" y="336"/> + <use xlink:href="#glyph0-23" x="392" y="336"/> + <use xlink:href="#glyph0-29" x="406" y="336"/> + <use xlink:href="#glyph0-6" x="420" y="336"/> + <use xlink:href="#glyph0-1" x="434" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 310 L 532 310 L 532 341 L 448 341 Z M 448 310 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="336"/> + <use xlink:href="#glyph0-6" x="462" y="336"/> + <use xlink:href="#glyph0-38" x="476" y="336"/> + <use xlink:href="#glyph0-4" x="490" y="336"/> + <use xlink:href="#glyph0-25" x="504" y="336"/> + <use xlink:href="#glyph0-6" x="518" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 310 L 546 310 L 546 341 L 532 341 Z M 532 310 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 310 L 588 310 L 588 341 L 546 341 Z M 546 310 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="336"/> + <use xlink:href="#glyph0-15" x="560" y="336"/> + <use xlink:href="#glyph0-33" x="574" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 310 L 1232 310 L 1232 341 L 588 341 Z M 588 310 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="336"/> + <use xlink:href="#glyph0-1" x="602" y="336"/> + <use xlink:href="#glyph0-46" x="616" y="336"/> + <use xlink:href="#glyph0-1" x="630" y="336"/> + <use xlink:href="#glyph0-19" x="644" y="336"/> + <use xlink:href="#glyph0-5" x="658" y="336"/> + <use xlink:href="#glyph0-6" x="672" y="336"/> + <use xlink:href="#glyph0-23" x="686" y="336"/> + <use xlink:href="#glyph0-24" x="700" y="336"/> + <use xlink:href="#glyph0-1" x="714" y="336"/> + <use xlink:href="#glyph0-26" x="728" y="336"/> + <use xlink:href="#glyph0-4" x="742" y="336"/> + <use xlink:href="#glyph0-16" x="756" y="336"/> + <use xlink:href="#glyph0-10" x="770" y="336"/> + <use xlink:href="#glyph0-15" x="784" y="336"/> + <use xlink:href="#glyph0-24" x="798" y="336"/> + <use xlink:href="#glyph0-34" x="812" y="336"/> + <use xlink:href="#glyph0-1" x="826" y="336"/> + <use xlink:href="#glyph0-1" x="840" y="336"/> + <use xlink:href="#glyph0-1" x="854" y="336"/> + <use xlink:href="#glyph0-1" x="868" y="336"/> + <use xlink:href="#glyph0-1" x="882" y="336"/> + <use xlink:href="#glyph0-1" x="896" y="336"/> + <use xlink:href="#glyph0-1" x="910" y="336"/> + <use xlink:href="#glyph0-1" x="924" y="336"/> + <use xlink:href="#glyph0-1" x="938" y="336"/> + <use xlink:href="#glyph0-1" x="952" y="336"/> + <use xlink:href="#glyph0-1" x="966" y="336"/> + <use xlink:href="#glyph0-1" x="980" y="336"/> + <use xlink:href="#glyph0-1" x="994" y="336"/> + <use xlink:href="#glyph0-1" x="1008" y="336"/> + <use xlink:href="#glyph0-1" x="1022" y="336"/> + <use xlink:href="#glyph0-1" x="1036" y="336"/> + <use xlink:href="#glyph0-1" x="1050" y="336"/> + <use xlink:href="#glyph0-1" x="1064" y="336"/> + <use xlink:href="#glyph0-1" x="1078" y="336"/> + <use xlink:href="#glyph0-1" x="1092" y="336"/> + <use xlink:href="#glyph0-1" x="1106" y="336"/> + <use xlink:href="#glyph0-1" x="1120" y="336"/> + <use xlink:href="#glyph0-1" x="1134" y="336"/> + <use xlink:href="#glyph0-1" x="1148" y="336"/> + <use xlink:href="#glyph0-1" x="1162" y="336"/> + <use xlink:href="#glyph0-1" x="1176" y="336"/> + <use xlink:href="#glyph0-1" x="1190" y="336"/> + <use xlink:href="#glyph0-1" x="1204" y="336"/> + <use xlink:href="#glyph0-1" x="1218" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 310 L 1260 310 L 1260 341 L 1232 341 Z M 1232 310 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="336"/> + <use xlink:href="#glyph0-45" x="1246" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 310 L 1400 310 L 1400 341 L 1260 341 Z M 1260 310 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(6.27451%,5.882353%,6.27451%);fill-opacity:1;" d="M 1400 310 L 1414 310 L 1414 341 L 1400 341 Z M 1400 310 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-38" x="1400" y="336"/> +</g> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-38" x="1401" y="336"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 310 L 1428 310 L 1428 341 L 1414 341 Z M 1414 310 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 0 341 L 14 341 L 14 372 L 0 372 Z M 0 341 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 14 341 L 168 341 L 168 372 L 14 372 Z M 14 341 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="14" y="367"/> + <use xlink:href="#glyph0-30" x="28" y="367"/> + <use xlink:href="#glyph0-34" x="42" y="367"/> + <use xlink:href="#glyph0-10" x="56" y="367"/> + <use xlink:href="#glyph0-26" x="70" y="367"/> + <use xlink:href="#glyph0-15" x="84" y="367"/> + <use xlink:href="#glyph0-14" x="98" y="367"/> + <use xlink:href="#glyph0-1" x="112" y="367"/> + <use xlink:href="#glyph0-35" x="126" y="367"/> + <use xlink:href="#glyph0-45" x="140" y="367"/> + <use xlink:href="#glyph0-1" x="154" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 341 L 182 341 L 182 372 L 168 372 Z M 168 341 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 341 L 266 341 L 266 372 L 182 372 Z M 182 341 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="367"/> + <use xlink:href="#glyph0-4" x="196" y="367"/> + <use xlink:href="#glyph0-14" x="210" y="367"/> + <use xlink:href="#glyph0-9" x="224" y="367"/> + <use xlink:href="#glyph0-15" x="238" y="367"/> + <use xlink:href="#glyph0-12" x="252" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 341 L 448 341 L 448 372 L 266 372 Z M 266 341 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="367"/> + <use xlink:href="#glyph0-7" x="280" y="367"/> + <use xlink:href="#glyph0-1" x="294" y="367"/> + <use xlink:href="#glyph0-46" x="308" y="367"/> + <use xlink:href="#glyph0-1" x="322" y="367"/> + <use xlink:href="#glyph0-47" x="336" y="367"/> + <use xlink:href="#glyph0-48" x="350" y="367"/> + <use xlink:href="#glyph0-1" x="364" y="367"/> + <use xlink:href="#glyph0-3" x="378" y="367"/> + <use xlink:href="#glyph0-23" x="392" y="367"/> + <use xlink:href="#glyph0-29" x="406" y="367"/> + <use xlink:href="#glyph0-6" x="420" y="367"/> + <use xlink:href="#glyph0-1" x="434" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 341 L 532 341 L 532 372 L 448 372 Z M 448 341 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="367"/> + <use xlink:href="#glyph0-6" x="462" y="367"/> + <use xlink:href="#glyph0-38" x="476" y="367"/> + <use xlink:href="#glyph0-4" x="490" y="367"/> + <use xlink:href="#glyph0-25" x="504" y="367"/> + <use xlink:href="#glyph0-6" x="518" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 341 L 546 341 L 546 372 L 532 372 Z M 532 341 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 341 L 588 341 L 588 372 L 546 372 Z M 546 341 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="367"/> + <use xlink:href="#glyph0-15" x="560" y="367"/> + <use xlink:href="#glyph0-33" x="574" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 341 L 1232 341 L 1232 372 L 588 372 Z M 588 341 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="367"/> + <use xlink:href="#glyph0-1" x="602" y="367"/> + <use xlink:href="#glyph0-46" x="616" y="367"/> + <use xlink:href="#glyph0-1" x="630" y="367"/> + <use xlink:href="#glyph0-31" x="644" y="367"/> + <use xlink:href="#glyph0-27" x="658" y="367"/> + <use xlink:href="#glyph0-18" x="672" y="367"/> + <use xlink:href="#glyph0-5" x="686" y="367"/> + <use xlink:href="#glyph0-4" x="700" y="367"/> + <use xlink:href="#glyph0-25" x="714" y="367"/> + <use xlink:href="#glyph0-23" x="728" y="367"/> + <use xlink:href="#glyph0-10" x="742" y="367"/> + <use xlink:href="#glyph0-6" x="756" y="367"/> + <use xlink:href="#glyph0-1" x="770" y="367"/> + <use xlink:href="#glyph0-18" x="784" y="367"/> + <use xlink:href="#glyph0-23" x="798" y="367"/> + <use xlink:href="#glyph0-14" x="812" y="367"/> + <use xlink:href="#glyph0-6" x="826" y="367"/> + <use xlink:href="#glyph0-1" x="840" y="367"/> + <use xlink:href="#glyph0-1" x="854" y="367"/> + <use xlink:href="#glyph0-1" x="868" y="367"/> + <use xlink:href="#glyph0-1" x="882" y="367"/> + <use xlink:href="#glyph0-1" x="896" y="367"/> + <use xlink:href="#glyph0-1" x="910" y="367"/> + <use xlink:href="#glyph0-1" x="924" y="367"/> + <use xlink:href="#glyph0-1" x="938" y="367"/> + <use xlink:href="#glyph0-1" x="952" y="367"/> + <use xlink:href="#glyph0-1" x="966" y="367"/> + <use xlink:href="#glyph0-1" x="980" y="367"/> + <use xlink:href="#glyph0-1" x="994" y="367"/> + <use xlink:href="#glyph0-1" x="1008" y="367"/> + <use xlink:href="#glyph0-1" x="1022" y="367"/> + <use xlink:href="#glyph0-1" x="1036" y="367"/> + <use xlink:href="#glyph0-1" x="1050" y="367"/> + <use xlink:href="#glyph0-1" x="1064" y="367"/> + <use xlink:href="#glyph0-1" x="1078" y="367"/> + <use xlink:href="#glyph0-1" x="1092" y="367"/> + <use xlink:href="#glyph0-1" x="1106" y="367"/> + <use xlink:href="#glyph0-1" x="1120" y="367"/> + <use xlink:href="#glyph0-1" x="1134" y="367"/> + <use xlink:href="#glyph0-1" x="1148" y="367"/> + <use xlink:href="#glyph0-1" x="1162" y="367"/> + <use xlink:href="#glyph0-1" x="1176" y="367"/> + <use xlink:href="#glyph0-1" x="1190" y="367"/> + <use xlink:href="#glyph0-1" x="1204" y="367"/> + <use xlink:href="#glyph0-1" x="1218" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 341 L 1260 341 L 1260 372 L 1232 372 Z M 1232 341 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="367"/> + <use xlink:href="#glyph0-45" x="1246" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1260 341 L 1358 341 L 1358 372 L 1260 372 Z M 1260 341 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-15" x="1260" y="367"/> + <use xlink:href="#glyph0-1" x="1274" y="367"/> + <use xlink:href="#glyph0-52" x="1288" y="367"/> + <use xlink:href="#glyph0-15" x="1302" y="367"/> + <use xlink:href="#glyph0-25" x="1316" y="367"/> + <use xlink:href="#glyph0-27" x="1330" y="367"/> + <use xlink:href="#glyph0-16" x="1344" y="367"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1358 341 L 1372 341 L 1372 372 L 1358 372 Z M 1358 341 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1372 341 L 1414 341 L 1414 372 L 1372 372 Z M 1372 341 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 341 L 1428 341 L 1428 372 L 1414 372 Z M 1414 341 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 372 L 56 372 L 56 403 L 0 403 Z M 0 372 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-46" x="0" y="398"/> + <use xlink:href="#glyph0-46" x="14" y="398"/> + <use xlink:href="#glyph0-46" x="28" y="398"/> + <use xlink:href="#glyph0-1" x="42" y="398"/> +</g> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-46" x="1" y="398"/> + <use xlink:href="#glyph0-46" x="15" y="398"/> + <use xlink:href="#glyph0-46" x="29" y="398"/> + <use xlink:href="#glyph0-1" x="43" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 56 372 L 140 372 L 140 403 L 56 403 Z M 56 372 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 372 L 168 372 L 168 403 L 140 403 Z M 140 372 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="398"/> + <use xlink:href="#glyph0-1" x="154" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 372 L 182 372 L 182 403 L 168 403 Z M 168 372 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 372 L 266 372 L 266 403 L 182 403 Z M 182 372 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="398"/> + <use xlink:href="#glyph0-4" x="196" y="398"/> + <use xlink:href="#glyph0-14" x="210" y="398"/> + <use xlink:href="#glyph0-9" x="224" y="398"/> + <use xlink:href="#glyph0-15" x="238" y="398"/> + <use xlink:href="#glyph0-12" x="252" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 372 L 448 372 L 448 403 L 266 403 Z M 266 372 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="398"/> + <use xlink:href="#glyph0-7" x="280" y="398"/> + <use xlink:href="#glyph0-1" x="294" y="398"/> + <use xlink:href="#glyph0-46" x="308" y="398"/> + <use xlink:href="#glyph0-1" x="322" y="398"/> + <use xlink:href="#glyph0-47" x="336" y="398"/> + <use xlink:href="#glyph0-48" x="350" y="398"/> + <use xlink:href="#glyph0-1" x="364" y="398"/> + <use xlink:href="#glyph0-3" x="378" y="398"/> + <use xlink:href="#glyph0-23" x="392" y="398"/> + <use xlink:href="#glyph0-29" x="406" y="398"/> + <use xlink:href="#glyph0-6" x="420" y="398"/> + <use xlink:href="#glyph0-1" x="434" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 372 L 532 372 L 532 403 L 448 403 Z M 448 372 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="398"/> + <use xlink:href="#glyph0-6" x="462" y="398"/> + <use xlink:href="#glyph0-38" x="476" y="398"/> + <use xlink:href="#glyph0-4" x="490" y="398"/> + <use xlink:href="#glyph0-25" x="504" y="398"/> + <use xlink:href="#glyph0-6" x="518" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 372 L 546 372 L 546 403 L 532 403 Z M 532 372 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 372 L 588 372 L 588 403 L 546 403 Z M 546 372 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="398"/> + <use xlink:href="#glyph0-15" x="560" y="398"/> + <use xlink:href="#glyph0-33" x="574" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 372 L 1232 372 L 1232 403 L 588 403 Z M 588 372 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="398"/> + <use xlink:href="#glyph0-1" x="602" y="398"/> + <use xlink:href="#glyph0-46" x="616" y="398"/> + <use xlink:href="#glyph0-1" x="630" y="398"/> + <use xlink:href="#glyph0-17" x="644" y="398"/> + <use xlink:href="#glyph0-4" x="658" y="398"/> + <use xlink:href="#glyph0-9" x="672" y="398"/> + <use xlink:href="#glyph0-6" x="686" y="398"/> + <use xlink:href="#glyph0-1" x="700" y="398"/> + <use xlink:href="#glyph0-16" x="714" y="398"/> + <use xlink:href="#glyph0-6" x="728" y="398"/> + <use xlink:href="#glyph0-23" x="742" y="398"/> + <use xlink:href="#glyph0-24" x="756" y="398"/> + <use xlink:href="#glyph0-25" x="770" y="398"/> + <use xlink:href="#glyph0-26" x="784" y="398"/> + <use xlink:href="#glyph0-1" x="798" y="398"/> + <use xlink:href="#glyph0-26" x="812" y="398"/> + <use xlink:href="#glyph0-4" x="826" y="398"/> + <use xlink:href="#glyph0-33" x="840" y="398"/> + <use xlink:href="#glyph0-26" x="854" y="398"/> + <use xlink:href="#glyph0-5" x="868" y="398"/> + <use xlink:href="#glyph0-4" x="882" y="398"/> + <use xlink:href="#glyph0-33" x="896" y="398"/> + <use xlink:href="#glyph0-26" x="910" y="398"/> + <use xlink:href="#glyph0-10" x="924" y="398"/> + <use xlink:href="#glyph0-4" x="938" y="398"/> + <use xlink:href="#glyph0-14" x="952" y="398"/> + <use xlink:href="#glyph0-33" x="966" y="398"/> + <use xlink:href="#glyph0-1" x="980" y="398"/> + <use xlink:href="#glyph0-1" x="994" y="398"/> + <use xlink:href="#glyph0-1" x="1008" y="398"/> + <use xlink:href="#glyph0-1" x="1022" y="398"/> + <use xlink:href="#glyph0-1" x="1036" y="398"/> + <use xlink:href="#glyph0-1" x="1050" y="398"/> + <use xlink:href="#glyph0-1" x="1064" y="398"/> + <use xlink:href="#glyph0-1" x="1078" y="398"/> + <use xlink:href="#glyph0-1" x="1092" y="398"/> + <use xlink:href="#glyph0-1" x="1106" y="398"/> + <use xlink:href="#glyph0-1" x="1120" y="398"/> + <use xlink:href="#glyph0-1" x="1134" y="398"/> + <use xlink:href="#glyph0-1" x="1148" y="398"/> + <use xlink:href="#glyph0-1" x="1162" y="398"/> + <use xlink:href="#glyph0-1" x="1176" y="398"/> + <use xlink:href="#glyph0-1" x="1190" y="398"/> + <use xlink:href="#glyph0-1" x="1204" y="398"/> + <use xlink:href="#glyph0-1" x="1218" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 372 L 1260 372 L 1260 403 L 1232 403 Z M 1232 372 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="398"/> + <use xlink:href="#glyph0-45" x="1246" y="398"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 372 L 1414 372 L 1414 403 L 1260 403 Z M 1260 372 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 372 L 1428 372 L 1428 403 L 1414 403 Z M 1414 372 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 403 L 140 403 L 140 434 L 0 434 Z M 0 403 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 403 L 168 403 L 168 434 L 140 434 Z M 140 403 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="429"/> + <use xlink:href="#glyph0-1" x="154" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 403 L 182 403 L 182 434 L 168 434 Z M 168 403 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 403 L 266 403 L 266 434 L 182 434 Z M 182 403 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="429"/> + <use xlink:href="#glyph0-4" x="196" y="429"/> + <use xlink:href="#glyph0-14" x="210" y="429"/> + <use xlink:href="#glyph0-9" x="224" y="429"/> + <use xlink:href="#glyph0-15" x="238" y="429"/> + <use xlink:href="#glyph0-12" x="252" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 403 L 448 403 L 448 434 L 266 434 Z M 266 403 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="429"/> + <use xlink:href="#glyph0-7" x="280" y="429"/> + <use xlink:href="#glyph0-1" x="294" y="429"/> + <use xlink:href="#glyph0-46" x="308" y="429"/> + <use xlink:href="#glyph0-1" x="322" y="429"/> + <use xlink:href="#glyph0-47" x="336" y="429"/> + <use xlink:href="#glyph0-48" x="350" y="429"/> + <use xlink:href="#glyph0-1" x="364" y="429"/> + <use xlink:href="#glyph0-3" x="378" y="429"/> + <use xlink:href="#glyph0-23" x="392" y="429"/> + <use xlink:href="#glyph0-29" x="406" y="429"/> + <use xlink:href="#glyph0-6" x="420" y="429"/> + <use xlink:href="#glyph0-1" x="434" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 403 L 532 403 L 532 434 L 448 434 Z M 448 403 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="429"/> + <use xlink:href="#glyph0-6" x="462" y="429"/> + <use xlink:href="#glyph0-38" x="476" y="429"/> + <use xlink:href="#glyph0-4" x="490" y="429"/> + <use xlink:href="#glyph0-25" x="504" y="429"/> + <use xlink:href="#glyph0-6" x="518" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 403 L 546 403 L 546 434 L 532 434 Z M 532 403 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 403 L 588 403 L 588 434 L 546 434 Z M 546 403 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="429"/> + <use xlink:href="#glyph0-15" x="560" y="429"/> + <use xlink:href="#glyph0-33" x="574" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 403 L 1232 403 L 1232 434 L 588 434 Z M 588 403 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="429"/> + <use xlink:href="#glyph0-1" x="602" y="429"/> + <use xlink:href="#glyph0-46" x="616" y="429"/> + <use xlink:href="#glyph0-1" x="630" y="429"/> + <use xlink:href="#glyph0-19" x="644" y="429"/> + <use xlink:href="#glyph0-24" x="658" y="429"/> + <use xlink:href="#glyph0-6" x="672" y="429"/> + <use xlink:href="#glyph0-23" x="686" y="429"/> + <use xlink:href="#glyph0-10" x="700" y="429"/> + <use xlink:href="#glyph0-6" x="714" y="429"/> + <use xlink:href="#glyph0-1" x="728" y="429"/> + <use xlink:href="#glyph0-52" x="742" y="429"/> + <use xlink:href="#glyph0-4" x="756" y="429"/> + <use xlink:href="#glyph0-5" x="770" y="429"/> + <use xlink:href="#glyph0-10" x="784" y="429"/> + <use xlink:href="#glyph0-6" x="798" y="429"/> + <use xlink:href="#glyph0-24" x="812" y="429"/> + <use xlink:href="#glyph0-1" x="826" y="429"/> + <use xlink:href="#glyph0-52" x="840" y="429"/> + <use xlink:href="#glyph0-24" x="854" y="429"/> + <use xlink:href="#glyph0-15" x="868" y="429"/> + <use xlink:href="#glyph0-43" x="882" y="429"/> + <use xlink:href="#glyph0-1" x="896" y="429"/> + <use xlink:href="#glyph0-16" x="910" y="429"/> + <use xlink:href="#glyph0-6" x="924" y="429"/> + <use xlink:href="#glyph0-23" x="938" y="429"/> + <use xlink:href="#glyph0-24" x="952" y="429"/> + <use xlink:href="#glyph0-25" x="966" y="429"/> + <use xlink:href="#glyph0-26" x="980" y="429"/> + <use xlink:href="#glyph0-1" x="994" y="429"/> + <use xlink:href="#glyph0-24" x="1008" y="429"/> + <use xlink:href="#glyph0-6" x="1022" y="429"/> + <use xlink:href="#glyph0-16" x="1036" y="429"/> + <use xlink:href="#glyph0-27" x="1050" y="429"/> + <use xlink:href="#glyph0-5" x="1064" y="429"/> + <use xlink:href="#glyph0-10" x="1078" y="429"/> + <use xlink:href="#glyph0-16" x="1092" y="429"/> + <use xlink:href="#glyph0-1" x="1106" y="429"/> + <use xlink:href="#glyph0-1" x="1120" y="429"/> + <use xlink:href="#glyph0-1" x="1134" y="429"/> + <use xlink:href="#glyph0-1" x="1148" y="429"/> + <use xlink:href="#glyph0-1" x="1162" y="429"/> + <use xlink:href="#glyph0-1" x="1176" y="429"/> + <use xlink:href="#glyph0-1" x="1190" y="429"/> + <use xlink:href="#glyph0-1" x="1204" y="429"/> + <use xlink:href="#glyph0-1" x="1218" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 403 L 1260 403 L 1260 434 L 1232 434 Z M 1232 403 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="429"/> + <use xlink:href="#glyph0-45" x="1246" y="429"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 403 L 1414 403 L 1414 434 L 1260 434 Z M 1260 403 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 403 L 1428 403 L 1428 434 L 1414 434 Z M 1414 403 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 434 L 140 434 L 140 465 L 0 465 Z M 0 434 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 434 L 168 434 L 168 465 L 140 465 Z M 140 434 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-45" x="140" y="460"/> + <use xlink:href="#glyph0-1" x="154" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 168 434 L 182 434 L 182 465 L 168 465 Z M 168 434 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-2" x="168" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 182 434 L 266 434 L 266 465 L 182 465 Z M 182 434 "/> +<g style="fill:rgb(53.333333%,93.72549%,53.333333%);fill-opacity:1;"> + <use xlink:href="#glyph0-13" x="182" y="460"/> + <use xlink:href="#glyph0-4" x="196" y="460"/> + <use xlink:href="#glyph0-14" x="210" y="460"/> + <use xlink:href="#glyph0-9" x="224" y="460"/> + <use xlink:href="#glyph0-15" x="238" y="460"/> + <use xlink:href="#glyph0-12" x="252" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 266 434 L 448 434 L 448 465 L 266 465 Z M 266 434 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="266" y="460"/> + <use xlink:href="#glyph0-7" x="280" y="460"/> + <use xlink:href="#glyph0-1" x="294" y="460"/> + <use xlink:href="#glyph0-46" x="308" y="460"/> + <use xlink:href="#glyph0-1" x="322" y="460"/> + <use xlink:href="#glyph0-47" x="336" y="460"/> + <use xlink:href="#glyph0-48" x="350" y="460"/> + <use xlink:href="#glyph0-1" x="364" y="460"/> + <use xlink:href="#glyph0-3" x="378" y="460"/> + <use xlink:href="#glyph0-23" x="392" y="460"/> + <use xlink:href="#glyph0-29" x="406" y="460"/> + <use xlink:href="#glyph0-6" x="420" y="460"/> + <use xlink:href="#glyph0-1" x="434" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 448 434 L 532 434 L 532 465 L 448 465 Z M 448 434 "/> +<g style="fill:rgb(57.254902%,85.098039%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-31" x="448" y="460"/> + <use xlink:href="#glyph0-6" x="462" y="460"/> + <use xlink:href="#glyph0-38" x="476" y="460"/> + <use xlink:href="#glyph0-4" x="490" y="460"/> + <use xlink:href="#glyph0-25" x="504" y="460"/> + <use xlink:href="#glyph0-6" x="518" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 532 434 L 546 434 L 546 465 L 532 465 Z M 532 434 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 546 434 L 588 434 L 588 465 L 546 465 Z M 546 434 "/> +<g style="fill:rgb(37.647059%,90.588235%,87.843137%);fill-opacity:1;"> + <use xlink:href="#glyph0-37" x="546" y="460"/> + <use xlink:href="#glyph0-15" x="560" y="460"/> + <use xlink:href="#glyph0-33" x="574" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 588 434 L 1232 434 L 1232 465 L 588 465 Z M 588 434 "/> +<g style="fill:rgb(100%,100%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-16" x="588" y="460"/> + <use xlink:href="#glyph0-1" x="602" y="460"/> + <use xlink:href="#glyph0-46" x="616" y="460"/> + <use xlink:href="#glyph0-1" x="630" y="460"/> + <use xlink:href="#glyph0-19" x="644" y="460"/> + <use xlink:href="#glyph0-5" x="658" y="460"/> + <use xlink:href="#glyph0-6" x="672" y="460"/> + <use xlink:href="#glyph0-23" x="686" y="460"/> + <use xlink:href="#glyph0-24" x="700" y="460"/> + <use xlink:href="#glyph0-50" x="714" y="460"/> + <use xlink:href="#glyph0-35" x="728" y="460"/> + <use xlink:href="#glyph0-6" x="742" y="460"/> + <use xlink:href="#glyph0-16" x="756" y="460"/> + <use xlink:href="#glyph0-6" x="770" y="460"/> + <use xlink:href="#glyph0-10" x="784" y="460"/> + <use xlink:href="#glyph0-1" x="798" y="460"/> + <use xlink:href="#glyph0-23" x="812" y="460"/> + <use xlink:href="#glyph0-25" x="826" y="460"/> + <use xlink:href="#glyph0-10" x="840" y="460"/> + <use xlink:href="#glyph0-4" x="854" y="460"/> + <use xlink:href="#glyph0-38" x="868" y="460"/> + <use xlink:href="#glyph0-6" x="882" y="460"/> + <use xlink:href="#glyph0-1" x="896" y="460"/> + <use xlink:href="#glyph0-52" x="910" y="460"/> + <use xlink:href="#glyph0-4" x="924" y="460"/> + <use xlink:href="#glyph0-5" x="938" y="460"/> + <use xlink:href="#glyph0-10" x="952" y="460"/> + <use xlink:href="#glyph0-6" x="966" y="460"/> + <use xlink:href="#glyph0-24" x="980" y="460"/> + <use xlink:href="#glyph0-16" x="994" y="460"/> + <use xlink:href="#glyph0-1" x="1008" y="460"/> + <use xlink:href="#glyph0-1" x="1022" y="460"/> + <use xlink:href="#glyph0-1" x="1036" y="460"/> + <use xlink:href="#glyph0-1" x="1050" y="460"/> + <use xlink:href="#glyph0-1" x="1064" y="460"/> + <use xlink:href="#glyph0-1" x="1078" y="460"/> + <use xlink:href="#glyph0-1" x="1092" y="460"/> + <use xlink:href="#glyph0-1" x="1106" y="460"/> + <use xlink:href="#glyph0-1" x="1120" y="460"/> + <use xlink:href="#glyph0-1" x="1134" y="460"/> + <use xlink:href="#glyph0-1" x="1148" y="460"/> + <use xlink:href="#glyph0-1" x="1162" y="460"/> + <use xlink:href="#glyph0-1" x="1176" y="460"/> + <use xlink:href="#glyph0-1" x="1190" y="460"/> + <use xlink:href="#glyph0-1" x="1204" y="460"/> + <use xlink:href="#glyph0-1" x="1218" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1232 434 L 1260 434 L 1260 465 L 1232 465 Z M 1232 434 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="1232" y="460"/> + <use xlink:href="#glyph0-45" x="1246" y="460"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 434 L 1414 434 L 1414 465 L 1260 465 Z M 1260 434 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 434 L 1428 434 L 1428 465 L 1414 465 Z M 1414 434 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 465 L 140 465 L 140 496 L 0 496 Z M 0 465 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 140 465 L 1260 465 L 1260 496 L 140 496 Z M 140 465 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-53" x="140" y="491"/> + <use xlink:href="#glyph0-41" x="154" y="491"/> + <use xlink:href="#glyph0-41" x="168" y="491"/> + <use xlink:href="#glyph0-41" x="182" y="491"/> + <use xlink:href="#glyph0-41" x="196" y="491"/> + <use xlink:href="#glyph0-41" x="210" y="491"/> + <use xlink:href="#glyph0-41" x="224" y="491"/> + <use xlink:href="#glyph0-41" x="238" y="491"/> + <use xlink:href="#glyph0-41" x="252" y="491"/> + <use xlink:href="#glyph0-41" x="266" y="491"/> + <use xlink:href="#glyph0-41" x="280" y="491"/> + <use xlink:href="#glyph0-41" x="294" y="491"/> + <use xlink:href="#glyph0-41" x="308" y="491"/> + <use xlink:href="#glyph0-41" x="322" y="491"/> + <use xlink:href="#glyph0-41" x="336" y="491"/> + <use xlink:href="#glyph0-41" x="350" y="491"/> + <use xlink:href="#glyph0-41" x="364" y="491"/> + <use xlink:href="#glyph0-41" x="378" y="491"/> + <use xlink:href="#glyph0-41" x="392" y="491"/> + <use xlink:href="#glyph0-41" x="406" y="491"/> + <use xlink:href="#glyph0-41" x="420" y="491"/> + <use xlink:href="#glyph0-41" x="434" y="491"/> + <use xlink:href="#glyph0-41" x="448" y="491"/> + <use xlink:href="#glyph0-41" x="462" y="491"/> + <use xlink:href="#glyph0-41" x="476" y="491"/> + <use xlink:href="#glyph0-41" x="490" y="491"/> + <use xlink:href="#glyph0-41" x="504" y="491"/> + <use xlink:href="#glyph0-41" x="518" y="491"/> + <use xlink:href="#glyph0-41" x="532" y="491"/> + <use xlink:href="#glyph0-41" x="546" y="491"/> + <use xlink:href="#glyph0-41" x="560" y="491"/> + <use xlink:href="#glyph0-41" x="574" y="491"/> + <use xlink:href="#glyph0-41" x="588" y="491"/> + <use xlink:href="#glyph0-41" x="602" y="491"/> + <use xlink:href="#glyph0-41" x="616" y="491"/> + <use xlink:href="#glyph0-41" x="630" y="491"/> + <use xlink:href="#glyph0-41" x="644" y="491"/> + <use xlink:href="#glyph0-41" x="658" y="491"/> + <use xlink:href="#glyph0-41" x="672" y="491"/> + <use xlink:href="#glyph0-41" x="686" y="491"/> + <use xlink:href="#glyph0-41" x="700" y="491"/> + <use xlink:href="#glyph0-41" x="714" y="491"/> + <use xlink:href="#glyph0-41" x="728" y="491"/> + <use xlink:href="#glyph0-41" x="742" y="491"/> + <use xlink:href="#glyph0-41" x="756" y="491"/> + <use xlink:href="#glyph0-41" x="770" y="491"/> + <use xlink:href="#glyph0-41" x="784" y="491"/> + <use xlink:href="#glyph0-41" x="798" y="491"/> + <use xlink:href="#glyph0-41" x="812" y="491"/> + <use xlink:href="#glyph0-41" x="826" y="491"/> + <use xlink:href="#glyph0-41" x="840" y="491"/> + <use xlink:href="#glyph0-41" x="854" y="491"/> + <use xlink:href="#glyph0-41" x="868" y="491"/> + <use xlink:href="#glyph0-41" x="882" y="491"/> + <use xlink:href="#glyph0-41" x="896" y="491"/> + <use xlink:href="#glyph0-41" x="910" y="491"/> + <use xlink:href="#glyph0-41" x="924" y="491"/> + <use xlink:href="#glyph0-41" x="938" y="491"/> + <use xlink:href="#glyph0-41" x="952" y="491"/> + <use xlink:href="#glyph0-41" x="966" y="491"/> + <use xlink:href="#glyph0-41" x="980" y="491"/> + <use xlink:href="#glyph0-41" x="994" y="491"/> + <use xlink:href="#glyph0-41" x="1008" y="491"/> + <use xlink:href="#glyph0-41" x="1022" y="491"/> + <use xlink:href="#glyph0-41" x="1036" y="491"/> + <use xlink:href="#glyph0-41" x="1050" y="491"/> + <use xlink:href="#glyph0-41" x="1064" y="491"/> + <use xlink:href="#glyph0-41" x="1078" y="491"/> + <use xlink:href="#glyph0-41" x="1092" y="491"/> + <use xlink:href="#glyph0-41" x="1106" y="491"/> + <use xlink:href="#glyph0-41" x="1120" y="491"/> + <use xlink:href="#glyph0-41" x="1134" y="491"/> + <use xlink:href="#glyph0-41" x="1148" y="491"/> + <use xlink:href="#glyph0-41" x="1162" y="491"/> + <use xlink:href="#glyph0-41" x="1176" y="491"/> + <use xlink:href="#glyph0-41" x="1190" y="491"/> + <use xlink:href="#glyph0-41" x="1204" y="491"/> + <use xlink:href="#glyph0-41" x="1218" y="491"/> + <use xlink:href="#glyph0-41" x="1232" y="491"/> + <use xlink:href="#glyph0-54" x="1246" y="491"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 1260 465 L 1414 465 L 1414 496 L 1260 496 Z M 1260 465 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 465 L 1428 465 L 1428 496 L 1414 496 Z M 1414 465 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 496 L 1414 496 L 1414 527 L 0 527 Z M 0 496 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 496 L 1428 496 L 1428 527 L 1414 527 Z M 1414 496 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 527 L 1414 527 L 1414 558 L 0 558 Z M 0 527 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 527 L 1428 527 L 1428 558 L 1414 558 Z M 1414 527 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 558 L 1414 558 L 1414 589 L 0 589 Z M 0 558 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 558 L 1428 558 L 1428 589 L 1414 589 Z M 1414 558 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 589 L 1414 589 L 1414 620 L 0 620 Z M 0 589 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 589 L 1428 589 L 1428 620 L 1414 620 Z M 1414 589 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 0 620 L 14 620 L 14 651 L 0 651 Z M 0 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 14 620 L 196 620 L 196 651 L 14 651 Z M 14 620 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-1" x="14" y="646"/> + <use xlink:href="#glyph0-30" x="28" y="646"/> + <use xlink:href="#glyph0-34" x="42" y="646"/> + <use xlink:href="#glyph0-10" x="56" y="646"/> + <use xlink:href="#glyph0-26" x="70" y="646"/> + <use xlink:href="#glyph0-15" x="84" y="646"/> + <use xlink:href="#glyph0-14" x="98" y="646"/> + <use xlink:href="#glyph0-1" x="112" y="646"/> + <use xlink:href="#glyph0-35" x="126" y="646"/> + <use xlink:href="#glyph0-6" x="140" y="646"/> + <use xlink:href="#glyph0-18" x="154" y="646"/> + <use xlink:href="#glyph0-5" x="168" y="646"/> + <use xlink:href="#glyph0-1" x="182" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 196 620 L 224 620 L 224 651 L 196 651 Z M 196 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 224 620 L 238 620 L 238 651 L 224 651 Z M 224 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 238 620 L 322 620 L 322 651 L 238 651 Z M 238 620 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-30" x="238" y="646"/> + <use xlink:href="#glyph0-23" x="252" y="646"/> + <use xlink:href="#glyph0-16" x="266" y="646"/> + <use xlink:href="#glyph0-10" x="280" y="646"/> + <use xlink:href="#glyph0-6" x="294" y="646"/> + <use xlink:href="#glyph0-1" x="308" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 322 620 L 406 620 L 406 651 L 322 651 Z M 322 620 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="322" y="646"/> + <use xlink:href="#glyph0-10" x="336" y="646"/> + <use xlink:href="#glyph0-24" x="350" y="646"/> + <use xlink:href="#glyph0-5" x="364" y="646"/> + <use xlink:href="#glyph0-28" x="378" y="646"/> + <use xlink:href="#glyph0-38" x="392" y="646"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="323" y="646"/> + <use xlink:href="#glyph0-10" x="337" y="646"/> + <use xlink:href="#glyph0-24" x="351" y="646"/> + <use xlink:href="#glyph0-5" x="365" y="646"/> + <use xlink:href="#glyph0-28" x="379" y="646"/> + <use xlink:href="#glyph0-38" x="393" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 406 620 L 420 620 L 420 651 L 406 651 Z M 406 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 420 620 L 448 620 L 448 651 L 420 651 Z M 420 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 448 620 L 462 620 L 462 651 L 448 651 Z M 448 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 462 620 L 644 620 L 644 651 L 462 651 Z M 462 620 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="462" y="646"/> + <use xlink:href="#glyph0-15" x="476" y="646"/> + <use xlink:href="#glyph0-18" x="490" y="646"/> + <use xlink:href="#glyph0-34" x="504" y="646"/> + <use xlink:href="#glyph0-1" x="518" y="646"/> + <use xlink:href="#glyph0-50" x="532" y="646"/> + <use xlink:href="#glyph0-1" x="546" y="646"/> + <use xlink:href="#glyph0-19" x="560" y="646"/> + <use xlink:href="#glyph0-5" x="574" y="646"/> + <use xlink:href="#glyph0-6" x="588" y="646"/> + <use xlink:href="#glyph0-23" x="602" y="646"/> + <use xlink:href="#glyph0-24" x="616" y="646"/> + <use xlink:href="#glyph0-1" x="630" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 644 620 L 728 620 L 728 651 L 644 651 Z M 644 620 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="644" y="646"/> + <use xlink:href="#glyph0-10" x="658" y="646"/> + <use xlink:href="#glyph0-24" x="672" y="646"/> + <use xlink:href="#glyph0-5" x="686" y="646"/> + <use xlink:href="#glyph0-28" x="700" y="646"/> + <use xlink:href="#glyph0-25" x="714" y="646"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-19" x="645" y="646"/> + <use xlink:href="#glyph0-10" x="659" y="646"/> + <use xlink:href="#glyph0-24" x="673" y="646"/> + <use xlink:href="#glyph0-5" x="687" y="646"/> + <use xlink:href="#glyph0-28" x="701" y="646"/> + <use xlink:href="#glyph0-25" x="715" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 728 620 L 742 620 L 742 651 L 728 651 Z M 728 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 742 620 L 770 620 L 770 651 L 742 651 Z M 742 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 770 620 L 784 620 L 784 651 L 770 651 Z M 770 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 784 620 L 840 620 L 840 651 L 784 651 Z M 784 620 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-35" x="784" y="646"/> + <use xlink:href="#glyph0-27" x="798" y="646"/> + <use xlink:href="#glyph0-14" x="812" y="646"/> + <use xlink:href="#glyph0-1" x="826" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 840 620 L 910 620 L 910 651 L 840 651 Z M 840 620 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-8" x="840" y="646"/> + <use xlink:href="#glyph0-14" x="854" y="646"/> + <use xlink:href="#glyph0-10" x="868" y="646"/> + <use xlink:href="#glyph0-6" x="882" y="646"/> + <use xlink:href="#glyph0-24" x="896" y="646"/> +</g> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-8" x="841" y="646"/> + <use xlink:href="#glyph0-14" x="855" y="646"/> + <use xlink:href="#glyph0-10" x="869" y="646"/> + <use xlink:href="#glyph0-6" x="883" y="646"/> + <use xlink:href="#glyph0-24" x="897" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 910 620 L 924 620 L 924 651 L 910 651 Z M 910 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 924 620 L 952 620 L 952 651 L 924 651 Z M 924 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 952 620 L 966 620 L 966 651 L 952 651 Z M 952 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 966 620 L 1092 620 L 1092 651 L 966 651 Z M 966 620 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-22" x="966" y="646"/> + <use xlink:href="#glyph0-6" x="980" y="646"/> + <use xlink:href="#glyph0-10" x="994" y="646"/> + <use xlink:href="#glyph0-10" x="1008" y="646"/> + <use xlink:href="#glyph0-4" x="1022" y="646"/> + <use xlink:href="#glyph0-14" x="1036" y="646"/> + <use xlink:href="#glyph0-33" x="1050" y="646"/> + <use xlink:href="#glyph0-16" x="1064" y="646"/> + <use xlink:href="#glyph0-1" x="1078" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1092 620 L 1106 620 L 1106 651 L 1092 651 Z M 1092 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1106 620 L 1302 620 L 1302 651 L 1106 651 Z M 1106 620 "/> +<g style="fill:rgb(87.843137%,90.196078%,94.117647%);fill-opacity:1;"> + <use xlink:href="#glyph0-25" x="1106" y="646"/> + <use xlink:href="#glyph0-5" x="1120" y="646"/> + <use xlink:href="#glyph0-4" x="1134" y="646"/> + <use xlink:href="#glyph0-25" x="1148" y="646"/> + <use xlink:href="#glyph0-29" x="1162" y="646"/> + <use xlink:href="#glyph0-1" x="1176" y="646"/> + <use xlink:href="#glyph0-10" x="1190" y="646"/> + <use xlink:href="#glyph0-15" x="1204" y="646"/> + <use xlink:href="#glyph0-1" x="1218" y="646"/> + <use xlink:href="#glyph0-52" x="1232" y="646"/> + <use xlink:href="#glyph0-15" x="1246" y="646"/> + <use xlink:href="#glyph0-25" x="1260" y="646"/> + <use xlink:href="#glyph0-27" x="1274" y="646"/> + <use xlink:href="#glyph0-16" x="1288" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(19.607843%,19.607843%,19.607843%);fill-opacity:1;" d="M 1302 620 L 1316 620 L 1316 651 L 1302 651 Z M 1302 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1316 620 L 1358 620 L 1358 651 L 1316 651 Z M 1316 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 1414 620 L 1428 620 L 1428 651 L 1414 651 Z M 1414 620 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(11.764706%,11.764706%,11.764706%);fill-opacity:1;" d="M 1358 620 L 1414 620 L 1414 651 L 1358 651 Z M 1358 620 "/> +<g style="fill:rgb(81.176471%,79.215686%,100%);fill-opacity:1;"> + <use xlink:href="#glyph0-55" x="1358" y="646"/> + <use xlink:href="#glyph0-56" x="1372" y="646"/> + <use xlink:href="#glyph0-56" x="1386" y="646"/> + <use xlink:href="#glyph0-55" x="1400" y="646"/> +</g> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(52.941176%,58.823529%,69.019608%);fill-opacity:1;" d="M 434 124 L 448 124 L 448 155 L 434 155 Z M 434 124 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 0 651 L 28 651 L 28 682 L 0 682 Z M 0 651 "/> +<path style=" stroke:none;fill-rule:nonzero;fill:rgb(14.117647%,15.686275%,21.568627%);fill-opacity:1;" d="M 28 651 L 1429 651 L 1429 682 L 28 682 Z M 28 651 "/> +</g> +</svg> diff --git a/pw_console/py/BUILD.gn b/pw_console/py/BUILD.gn index efa80ed11..b7164c95b 100644 --- a/pw_console/py/BUILD.gn +++ b/pw_console/py/BUILD.gn @@ -25,6 +25,7 @@ pw_python_package("py") { sources = [ "pw_console/__init__.py", "pw_console/__main__.py", + "pw_console/command_runner.py", "pw_console/console_app.py", "pw_console/console_prefs.py", "pw_console/embed.py", @@ -73,6 +74,7 @@ pw_python_package("py") { "pw_console/yaml_config_loader_mixin.py", ] tests = [ + "command_runner_test.py", "console_app_test.py", "console_prefs_test.py", "help_window_test.py", diff --git a/pw_console/py/command_runner_test.py b/pw_console/py/command_runner_test.py new file mode 100644 index 000000000..45362fe90 --- /dev/null +++ b/pw_console/py/command_runner_test.py @@ -0,0 +1,258 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Tests for pw_console.command_runner dialog.""" + +import logging +import re +import unittest +from typing import Callable, List, Tuple + +from unittest.mock import MagicMock + +from prompt_toolkit.application import create_app_session +from prompt_toolkit.output import ColorDepth +# inclusive-language: ignore +from prompt_toolkit.output import DummyOutput as FakeOutput + +from pw_console.console_app import ConsoleApp +from pw_console.console_prefs import ConsolePrefs +from pw_console.text_formatting import ( + flatten_formatted_text_tuples, + join_adjacent_style_tuples, +) +from window_manager_test import target_list_and_pane, window_pane_titles + + +def _create_console_app(log_pane_count=2): + console_app = ConsoleApp(color_depth=ColorDepth.DEPTH_8_BIT, + prefs=ConsolePrefs(project_file=False, + project_user_file=False, + user_file=False)) + console_app.prefs.reset_config() + + # Setup log panes + loggers = {} + for i in range(log_pane_count): + loggers['LogPane-{}'.format(i)] = [ + logging.getLogger('test_log{}'.format(i)) + ] + for window_title, logger_instances in loggers.items(): + console_app.add_log_handler(window_title, logger_instances) + + return console_app + + +class TestCommandRunner(unittest.TestCase): + """Tests for CommandRunner.""" + def setUp(self): + self.maxDiff = None # pylint: disable=invalid-name + + def test_flatten_menu_items(self) -> None: + with create_app_session(output=FakeOutput()): + console_app = _create_console_app(log_pane_count=2) + flattened_menu_items = [ + text for text, handler in + console_app.command_runner.load_menu_items() + ] + + # Check some common menu items exist. + self.assertIn('[File] > Open Logger', flattened_menu_items) + self.assertIn('[File] > Themes > UI Themes > High Contrast', + flattened_menu_items) + self.assertIn('[Help] > User Guide', flattened_menu_items) + self.assertIn('[Help] > Keyboard Shortcuts', flattened_menu_items) + # Check for log windows + self.assertRegex( + '\n'.join(flattened_menu_items), + re.compile(r'^\[Windows\] > .* LogPane-[0-9]+ > .*$', + re.MULTILINE), + ) + + def test_filter_and_highlight_matches(self) -> None: + """Check filtering matches and highlighting works correctly.""" + with create_app_session(output=FakeOutput()): + console_app = _create_console_app(log_pane_count=2) + command_runner = console_app.command_runner + + command_runner.filter_completions = MagicMock( + wraps=command_runner.filter_completions) + command_runner.width = 20 + + # Define custom completion items + def empty_handler() -> None: + return None + + def get_completions() -> List[Tuple[str, Callable]]: + return [ + ('[File] > Open Logger', empty_handler), + ('[Windows] > 1: Host Logs > Show/Hide', empty_handler), + ('[Windows] > 2: Device Logs > Show/Hide', empty_handler), + ('[Help] > User Guide', empty_handler), + ] + + command_runner.filter_completions.assert_not_called() + command_runner.set_completions(window_title='Test Completions', + load_completions=get_completions) + command_runner.filter_completions.assert_called_once() + command_runner.filter_completions.reset_mock() + + # Input field should be empty + self.assertEqual(command_runner.input_field.buffer.text, '') + # Flatten resulting formatted text + result_items = join_adjacent_style_tuples( + flatten_formatted_text_tuples( + command_runner.completion_fragments)) + + # index 0: the selected line + # index 1: the rest of the completions with line breaks + self.assertEqual(len(result_items), 2) + first_item_style = result_items[0][0] + first_item_text = result_items[0][1] + second_item_text = result_items[1][1] + # Check expected number of lines are present + self.assertEqual(len(first_item_text.splitlines()), 1) + self.assertEqual(len(second_item_text.splitlines()), 3) + # First line is highlighted as a selected item + self.assertEqual(first_item_style, + 'class:command-runner-selected-item') + self.assertIn('[File] > Open Logger', first_item_text) + + # Type: file open + command_runner.input_field.buffer.text = 'file open' + self.assertEqual(command_runner.input_field.buffer.text, + 'file open') + # Run the filter + command_runner.filter_completions() + # Flatten resulting formatted text + result_items = join_adjacent_style_tuples( + flatten_formatted_text_tuples( + command_runner.completion_fragments)) + # Check file and open are highlighted + self.assertEqual( + result_items[:4], + [ + ('class:command-runner-selected-item', '['), + ('class:command-runner-selected-item ' + 'class:command-runner-fuzzy-highlight-0 ', 'File'), + ('class:command-runner-selected-item', '] > '), + ('class:command-runner-selected-item ' + 'class:command-runner-fuzzy-highlight-1 ', 'Open'), + ], + ) + + # Type: open file + command_runner.input_field.buffer.text = 'open file' + # Run the filter + command_runner.filter_completions() + result_items = join_adjacent_style_tuples( + flatten_formatted_text_tuples( + command_runner.completion_fragments)) + # Check file and open are highlighted, the fuzzy-highlight class + # should be swapped. + self.assertEqual( + result_items[:4], + [ + ('class:command-runner-selected-item', '['), + ('class:command-runner-selected-item ' + 'class:command-runner-fuzzy-highlight-1 ', 'File'), + ('class:command-runner-selected-item', '] > '), + ('class:command-runner-selected-item ' + 'class:command-runner-fuzzy-highlight-0 ', 'Open'), + ], + ) + + # Clear input + command_runner._reset_selected_item() # pylint: disable=protected-access + command_runner.filter_completions() + result_items = join_adjacent_style_tuples( + flatten_formatted_text_tuples( + command_runner.completion_fragments)) + self.assertEqual(len(first_item_text.splitlines()), 1) + self.assertEqual(len(second_item_text.splitlines()), 3) + + # Press down (select the next item) + command_runner._next_item() # pylint: disable=protected-access + # Filter and check results + command_runner.filter_completions() + result_items = join_adjacent_style_tuples( + flatten_formatted_text_tuples( + command_runner.completion_fragments)) + self.assertEqual(len(result_items), 3) + # First line - not selected + self.assertEqual(result_items[0], ('', '[File] > Open Logger\n')) + # Second line - is selected + self.assertEqual(result_items[1], + ('class:command-runner-selected-item', + '[Windows] > 1: Host Logs > Show/Hide\n')) + # Third and fourth lines separated by \n - not selected + self.assertEqual(result_items[2], + ('', '[Windows] > 2: Device Logs > Show/Hide\n' + '[Help] > User Guide')) + + def test_run_action(self) -> None: + """Check running an action works correctly.""" + with create_app_session(output=FakeOutput()): + console_app = _create_console_app(log_pane_count=2) + command_runner = console_app.command_runner + self.assertEqual( + window_pane_titles(console_app.window_manager), + [ + # Split 1 + [ + 'LogPane-1 - test_log1', + 'LogPane-0 - test_log0', + 'Python Repl - ', + ], + ], + ) + command_runner.open_dialog() + # Set LogPane-1 as the focused window pane + target_list_and_pane(console_app.window_manager, 0, 0) + + command_runner.input_field.buffer.text = 'move right' + + # pylint: disable=protected-access + command_runner._make_regexes = MagicMock( + wraps=command_runner._make_regexes) + # pylint: enable=protected-access + command_runner.filter_completions() + # Filter should only be re-run if input text changed + command_runner.filter_completions() + command_runner._make_regexes.assert_called_once() # pylint: disable=protected-access + + self.assertIn('[View] > Move Window Right', + command_runner.selected_item_text) + # Run the Move Window Right action + command_runner._run_selected_item() # pylint: disable=protected-access + # Dialog should be closed + self.assertFalse(command_runner.show_dialog) + # LogPane-1 should be moved to the right in it's own split + self.assertEqual( + window_pane_titles(console_app.window_manager), + [ + # Split 1 + [ + 'LogPane-0 - test_log0', + 'Python Repl - ', + ], + # Split 2 + [ + 'LogPane-1 - test_log1', + ], + ], + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/pw_console/py/log_view_test.py b/pw_console/py/log_view_test.py index da843166d..a21a5647d 100644 --- a/pw_console/py/log_view_test.py +++ b/pw_console/py/log_view_test.py @@ -43,7 +43,9 @@ def _create_log_view(): log_pane.current_log_pane_height = 10 application = MagicMock() - application.prefs = ConsolePrefs() + application.prefs = ConsolePrefs(project_file=False, + project_user_file=False, + user_file=False) application.prefs.reset_config() log_view = LogView(log_pane, application) return log_view, log_pane diff --git a/pw_console/py/pw_console/command_runner.py b/pw_console/py/pw_console/command_runner.py new file mode 100644 index 000000000..3aff8a047 --- /dev/null +++ b/pw_console/py/pw_console/command_runner.py @@ -0,0 +1,517 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""CommandRunner dialog classes.""" + +from __future__ import annotations +import functools +import logging +import re +from typing import ( + Callable, + Iterable, + Iterator, + List, + Optional, + TYPE_CHECKING, + Tuple, +) + +from prompt_toolkit.buffer import Buffer +from prompt_toolkit.filters import Condition +from prompt_toolkit.formatted_text import StyleAndTextTuples +from prompt_toolkit.formatted_text.utils import fragment_list_to_text +from prompt_toolkit.layout.utils import explode_text_fragments +from prompt_toolkit.history import InMemoryHistory +from prompt_toolkit.key_binding import ( + KeyBindings, + KeyBindingsBase, + KeyPressEvent, +) +from prompt_toolkit.layout import ( + AnyContainer, + ConditionalContainer, + DynamicContainer, + FormattedTextControl, + HSplit, + VSplit, + Window, + WindowAlign, +) +from prompt_toolkit.widgets import MenuItem +from prompt_toolkit.widgets import TextArea + +import pw_console.widgets.border +import pw_console.widgets.checkbox +import pw_console.widgets.mouse_handlers + +if TYPE_CHECKING: + from pw_console.console_app import ConsoleApp + +_LOG = logging.getLogger(__package__) + + +def flatten_menu_items(items: List[MenuItem], + prefix: str = '') -> Iterator[Tuple[str, Callable]]: + """Flatten nested prompt_toolkit MenuItems into text and callable tuples.""" + for item in items: + new_text = [] + if prefix: + new_text.append(prefix) + new_text.append(item.text) + new_prefix = ' > '.join(new_text) + + if item.children: + yield from flatten_menu_items(item.children, new_prefix) + elif item.handler: + # Skip this item if it's a separator or disabled. + if item.text == '-' or item.disabled: + continue + yield (new_prefix, item.handler) + + +def highlight_matches( + regexes: Iterable[re.Pattern], + line_fragments: StyleAndTextTuples) -> StyleAndTextTuples: + """Highlight regex matches in prompt_toolkit FormattedTextTuples.""" + line_text = fragment_list_to_text(line_fragments) + exploded_fragments = explode_text_fragments(line_fragments) + + def apply_highlighting(fragments: StyleAndTextTuples, + index: int, + matching_regex_index: int = 0) -> None: + # Expand all fragments and apply the highlighting style. + old_style, _text, *_ = fragments[index] + # There are 6 fuzzy-highlight styles defined in style.py. Get an index + # from 0-5 to use one style after the other in turn. + style_index = matching_regex_index % 6 + fragments[index] = ( + old_style + + f' class:command-runner-fuzzy-highlight-{style_index} ', + fragments[index][1], + ) + + # Highlight each non-overlapping search match. + for regex_i, regex in enumerate(regexes): + for match in regex.finditer(line_text): + for fragment_i in range(match.start(), match.end()): + apply_highlighting(exploded_fragments, fragment_i, regex_i) + + return exploded_fragments + + +class CommandRunner: + """CommandRunner dialog box.""" + + # pylint: disable=too-many-instance-attributes + + def __init__( + self, + application: ConsoleApp, + window_title: str = None, + load_completions: Optional[Callable[[], + List[Tuple[str, + Callable]]]] = None, + width: int = 80, + height: int = 10): + # Parent pw_console application + self.application = application + # Visibility toggle + self.show_dialog = False + # Tracks the last focused container, to enable restoring focus after + # closing the dialog. + self.last_focused_pane = None + + # List of all possible completion items + self.completions: List[Tuple[str, Callable]] = [] + # Formatted text fragments of matched items + self.completion_fragments: List[StyleAndTextTuples] = [] + + # Current selected item tracking variables + self.selected_item: int = 0 + self.selected_item_text: str = '' + self.selected_item_handler: Optional[Callable] = None + # Previous input text + self.last_input_field_text: str = 'EMPTY' + # Previous selected item + self.last_selected_item: int = 0 + + # Dialog width, height and title + self.width = width + self.height = height + self.window_title: str + + # Callable to fetch completion items + self.load_completions: Callable[[], List[Tuple[str, Callable]]] + + # Command runner text input field + self.input_field = TextArea( + prompt=[ + ('class:command-runner-setting', '> ', + functools.partial(pw_console.widgets.mouse_handlers.on_click, + self.focus_self)) + ], + focusable=True, + focus_on_click=True, + scrollbar=False, + multiline=False, + height=1, + dont_extend_height=True, + dont_extend_width=False, + accept_handler=self._command_accept_handler, + history=InMemoryHistory(), + ) + # Set additional keybindings for the input field + self.input_field.control.key_bindings = self._create_key_bindings() + + # Container for the Cancel and Run buttons + input_field_buttons_container = ConditionalContainer( + Window( + content=FormattedTextControl( + self._get_input_field_button_fragments, + focusable=False, + show_cursor=False, + ), + height=1, + align=WindowAlign.RIGHT, + dont_extend_width=True, + ), + filter=Condition(lambda: self.content_width() > 40), + ) + + # Container for completion matches + command_items_window = Window( + content=FormattedTextControl( + self.render_completion_items, + show_cursor=False, + focusable=False, + ), + align=WindowAlign.LEFT, + dont_extend_width=False, + height=self.height, + ) + + # Main content HSplit + self.command_runner_content = HSplit( + [ + # Input field and buttons on the same line + VSplit([ + self.input_field, + input_field_buttons_container, + ]), + # Completion items below + command_items_window, + ], + style='class:command-runner class:theme-fg-default', + ) + + # Set completions if passed in. + self.set_completions(window_title, load_completions) + + # bordered_content wraps the above command_runner_content in a border. + self.bordered_content: AnyContainer + # Root prompt_toolkit container + self.container = ConditionalContainer( + DynamicContainer(lambda: self.bordered_content), + filter=Condition(lambda: self.show_dialog), + ) + + def _create_bordered_content(self) -> None: + """Wrap self.command_runner_content in a border.""" + # This should be called whenever the window_title changes. + self.bordered_content = pw_console.widgets.border.create_border( + self.command_runner_content, + title=self.window_title, + border_style='class:command-runner-border', + left_margin_columns=1, + right_margin_columns=1, + ) + + def __pt_container__(self) -> AnyContainer: + """Return the prompt_toolkit root container for this dialog.""" + return self.container + + def _create_key_bindings(self) -> KeyBindingsBase: + """Create additional key bindings for the command input field.""" + key_bindings = KeyBindings() + + @key_bindings.add('escape') + @key_bindings.add('c-c') + def _cancel(_event: KeyPressEvent) -> None: + """Clear input or close command.""" + if self._get_input_field_text() != '': + self._reset_selected_item() + return + + self.close_dialog() + + @key_bindings.add('up') + @key_bindings.add('s-tab') + def _select_previous_item(_event: KeyPressEvent) -> None: + """Select previous completion item.""" + self._previous_item() + + @key_bindings.add('down') + @key_bindings.add('tab') + def _select_next_item(_event: KeyPressEvent) -> None: + """Select next completion item.""" + self._next_item() + + return key_bindings + + def content_width(self) -> int: + """Return the smaller value of self.width and the available width.""" + window_manager_width = ( + self.application.window_manager.current_window_manager_width) + if not window_manager_width: + window_manager_width = self.width + return min(self.width, window_manager_width) + + def focus_self(self) -> None: + self.application.layout.focus(self) + + def close_dialog(self) -> None: + """Close command runner dialog box.""" + self.show_dialog = False + self._reset_selected_item() + + # Restore original focus if possible. + if self.last_focused_pane: + self.application.focus_on_container(self.last_focused_pane) + else: + # Fallback to focusing on the main menu. + self.application.focus_main_menu() + + def open_dialog(self) -> None: + self.show_dialog = True + self.last_focused_pane = self.application.focused_window() + self.focus_self() + self.application.redraw_ui() + + def set_completions( + self, + window_title: str = None, + load_completions: Optional[Callable[[], List[Tuple[str, + Callable]]]] = None, + ) -> None: + """Set window title and callable to fetch possible completions. + + Call this function whenever new completion items need to be loaded. + """ + self.window_title = window_title if window_title else 'Menu Items' + self.load_completions = (load_completions + if load_completions else self.load_menu_items) + self._reset_selected_item() + + self.completions = [] + self.completion_fragments = [] + + # Load and filter completions + self.filter_completions() + + # (Re)create the bordered content with the window_title set. + self._create_bordered_content() + + def reload_completions(self) -> None: + self.completions = self.load_completions() + + def load_menu_items(self) -> List[Tuple[str, Callable]]: + # pylint: disable=no-self-use + return list(flatten_menu_items(self.application.menu_items)) + + def _get_input_field_text(self) -> str: + return self.input_field.buffer.text + + def _make_regexes(self, input_text) -> List[re.Pattern]: + # pylint: disable=no-self-use + regexes: List[re.Pattern] = [] + if not input_text: + return regexes + + text_tokens = input_text.split(' ') + if len(text_tokens) > 0: + regexes = [ + re.compile(re.escape(text), re.IGNORECASE) + for text in text_tokens + ] + + return regexes + + def _matches_orderless(self, regexes: List[re.Pattern], text) -> bool: + """Check if all supplied regexs match the input text.""" + # pylint: disable=no-self-use + return all(regex.search(text) for regex in regexes) + + def filter_completions(self) -> None: + """Filter completion items if new user input detected.""" + if not self.input_text_changed() and not self.selected_item_changed(): + return + + self.reload_completions() + + input_text = self._get_input_field_text() + self.completion_fragments = [] + + regexes = self._make_regexes(input_text) + check_match = self._matches_orderless + + i = 0 + for text, handler in self.completions: + if not (input_text == '' or check_match(regexes, text)): + continue + style = '' + if i == self.selected_item: + style = 'class:command-runner-selected-item' + self.selected_item_text = text + self.selected_item_handler = handler + text = text.ljust(self.content_width()) + fragments: StyleAndTextTuples = highlight_matches( + regexes, [(style, text + '\n')]) + self.completion_fragments.append(fragments) + i += 1 + + def input_text_changed(self) -> bool: + """Return True if text in the input field has changed.""" + input_text = self._get_input_field_text() + if input_text != self.last_input_field_text: + self.last_input_field_text = input_text + self.selected_item = 0 + return True + return False + + def selected_item_changed(self) -> bool: + """Check if the user pressed up or down to select a different item.""" + return self.last_selected_item != self.selected_item + + def _next_item(self) -> None: + self.last_selected_item = self.selected_item + self.selected_item = min( + # Don't move past the height of the window or the length of possible + # items. + min(self.height, len(self.completion_fragments)) - 1, + self.selected_item + 1) + self.application.redraw_ui() + + def _previous_item(self) -> None: + self.last_selected_item = self.selected_item + self.selected_item = max(0, self.selected_item - 1) + self.application.redraw_ui() + + def _get_input_field_button_fragments(self) -> StyleAndTextTuples: + # Mouse handlers + focus = functools.partial(pw_console.widgets.mouse_handlers.on_click, + self.focus_self) + cancel = functools.partial(pw_console.widgets.mouse_handlers.on_click, + self.close_dialog) + select_item = functools.partial( + pw_console.widgets.mouse_handlers.on_click, + self._run_selected_item) + + separator_text = ('', ' ', focus) + + # Default button style + button_style = 'class:toolbar-button-inactive' + + fragments: StyleAndTextTuples = [] + + # Cancel button + fragments.extend( + pw_console.widgets.checkbox.to_keybind_indicator( + key='Ctrl-c', + description='Cancel', + mouse_handler=cancel, + base_style=button_style, + )) + fragments.append(separator_text) + + # Run button + fragments.extend( + pw_console.widgets.checkbox.to_keybind_indicator( + 'Enter', 'Run', select_item, base_style=button_style)) + return fragments + + def render_completion_items(self) -> StyleAndTextTuples: + """Render completion items.""" + fragments: StyleAndTextTuples = [] + + # Update completions if any state change since the last render (new text + # entered or arrow keys pressed). + self.filter_completions() + + for completion_item in self.completion_fragments: + fragments.extend(completion_item) + + return fragments + + def _reset_selected_item(self) -> None: + self.selected_item = 0 + self.last_selected_item = 0 + self.selected_item_text = '' + self.selected_item_handler = None + self.last_input_field_text = 'EMPTY' + self.input_field.buffer.reset() + + def _run_selected_item(self) -> None: + """Run the selected action.""" + if not self.selected_item_handler: + return + # Save the selected item handler. This is reset by self.close_dialog() + handler = self.selected_item_handler + + # Depending on what action is run, the command runner dialog may need to + # be closed, left open, or closed before running the selected action. + close_dialog = True + close_dialog_first = False + + # Actions that launch new command runners, close_dialog should not run. + for command_text in [ + '[File] > Open Logger', + ]: + if command_text in self.selected_item_text: + close_dialog = False + break + + # Actions that change what is in focus should be run after closing the + # command runner dialog. + for command_text in [ + '[View] > Focus Next Window/Tab', + '[View] > Focus Prev Window/Tab', + # All help menu entries open popup windows. + '[Help] > ', + # This focuses on a save dialog bor. + 'Save/Export a copy', + ]: + if command_text in self.selected_item_text: + close_dialog_first = True + break + + # Close first if needed + if close_dialog and close_dialog_first: + self.close_dialog() + + # Run the selected item handler + handler() + + # If not already closed earlier. + if close_dialog and not close_dialog_first: + self.close_dialog() + + def _command_accept_handler(self, _buff: Buffer) -> bool: + """Function run when pressing Enter in the command runner input box.""" + # If at least one match is available + if len(self.completion_fragments) > 0: + self._run_selected_item() + # Erase input text + return False + # Keep input text + return True diff --git a/pw_console/py/pw_console/console_app.py b/pw_console/py/pw_console/console_app.py index d988dd9e6..78939de2c 100644 --- a/pw_console/py/pw_console/console_app.py +++ b/pw_console/py/pw_console/console_app.py @@ -21,7 +21,7 @@ import os from pathlib import Path import sys from threading import Thread -from typing import Callable, Iterable, Optional, Union +from typing import Any, Callable, Iterable, List, Optional, Tuple, Union from jinja2 import Environment, FileSystemLoader, make_logging_undefined from prompt_toolkit.clipboard.pyperclip import PyperclipClipboard @@ -56,6 +56,7 @@ from ptpython.key_bindings import ( # type: ignore from pw_console.console_prefs import ConsolePrefs from pw_console.help_window import HelpWindow +from pw_console.command_runner import CommandRunner import pw_console.key_bindings from pw_console.log_pane import LogPane from pw_console.log_store import LogStore @@ -123,7 +124,7 @@ def get_default_colordepth( class ConsoleApp: """The main ConsoleApp class that glues everything together.""" - # pylint: disable=too-many-instance-attributes + # pylint: disable=too-many-instance-attributes,too-many-public-methods def __init__( self, global_vars=None, @@ -187,10 +188,10 @@ class ConsoleApp: self.message.extend( pw_console.widgets.checkbox.to_keybind_indicator( - 'F1', - 'Help', + 'Ctrl-p', + 'Search Menu', functools.partial(pw_console.widgets.mouse_handlers.on_click, - self.user_guide_window.toggle_display), + self.open_command_runner_main_menu), base_style='class:toolbar-button-inactive', )) # One space separator @@ -241,63 +242,77 @@ class ConsoleApp: # Create help window text based global key_bindings and active panes. self._update_help_window() + self.command_runner = CommandRunner( + self, + width=self.prefs.command_runner_width, + height=self.prefs.command_runner_height, + ) + + self.floats = [ + # Top message bar + Float( + content=FloatingMessageBar(self), + top=0, + right=0, + height=1, + ), + # Centered floating help windows + Float( + content=self.app_help_window, + top=2, + bottom=2, + # Callable to get width + width=self.app_help_window.content_width, + ), + Float( + content=self.user_guide_window, + top=2, + bottom=2, + # Callable to get width + width=self.user_guide_window.content_width, + ), + Float( + content=self.keybind_help_window, + top=2, + bottom=2, + # Callable to get width + width=self.keybind_help_window.content_width, + ), + # Completion menu that can overlap other panes since it lives in + # the top level Float container. + Float( + xcursor=True, + ycursor=True, + content=ConditionalContainer( + content=CompletionsMenu( + scroll_offset=(lambda: self.pw_ptpython_repl. + completion_menu_scroll_offset), + max_height=16, + ), + # Only show our completion if ptpython's is disabled. + filter=Condition( + lambda: self.pw_ptpython_repl.completion_visualisation + == CompletionVisualisation.NONE), + ), + ), + Float( + content=self.command_runner, + # Callable to get width + width=self.command_runner.content_width, + **self.prefs.command_runner_position, + ), + Float( + content=self.quit_dialog, + top=2, + left=2, + ), + ] + # prompt_toolkit root container. self.root_container = MenuContainer( body=self.window_manager.create_root_container(), menu_items=self.menu_items, - floats=[ - # Top message bar - Float( - content=FloatingMessageBar(self), - top=0, - right=0, - height=1, - ), - # Centered floating help windows - Float( - content=self.app_help_window, - top=2, - bottom=2, - # Callable to get width - width=self.app_help_window.content_width, - ), - Float( - content=self.user_guide_window, - top=2, - bottom=2, - # Callable to get width - width=self.user_guide_window.content_width, - ), - Float( - content=self.keybind_help_window, - top=2, - bottom=2, - # Callable to get width - width=self.keybind_help_window.content_width, - ), - Float( - content=self.quit_dialog, - top=2, - left=2, - ), - # Completion menu that can overlap other panes since it lives in - # the top level Float container. - Float( - xcursor=True, - ycursor=True, - content=ConditionalContainer( - content=CompletionsMenu( - scroll_offset=(lambda: self.pw_ptpython_repl. - completion_menu_scroll_offset), - max_height=16, - ), - # Only show our completion if ptpython's is disabled. - filter=Condition(lambda: self.pw_ptpython_repl. - completion_visualisation == - CompletionVisualisation.NONE), - ), - ), - ], + floats=self.floats, ) # NOTE: ptpython stores it's completion menus in this HSplit: @@ -324,7 +339,6 @@ class ConsoleApp: # Create the prompt_toolkit Application instance. self.application: Application = Application( layout=self.layout, - after_render=self.run_after_render_hooks, key_bindings=merge_key_bindings([ # Pull key bindings from ptpython load_python_bindings(self.pw_ptpython_repl), @@ -393,24 +407,37 @@ class ConsoleApp: self.menu_items = self._create_menu_items() self.root_container.menu_items = self.menu_items - def _create_logger_submenu(self): - submenu = [ - MenuItem( + def open_command_runner_main_menu(self) -> None: + self.command_runner.set_completions() + if not self.command_runner_is_open(): + self.command_runner.open_dialog() + + def open_command_runner_loggers(self) -> None: + self.command_runner.set_completions( + window_title='Open Logger', + load_completions=self._create_logger_completions) + if not self.command_runner_is_open(): + self.command_runner.open_dialog() + + def _create_logger_completions(self) -> List[Tuple[str, Callable]]: + completions: List[Tuple[str, Callable]] = [ + ( 'root', - handler=functools.partial(self.open_new_log_pane_for_logger, - '', - window_title='root'), - ) + functools.partial(self.open_new_log_pane_for_logger, + '', + window_title='root'), + ), ] + all_logger_names = sorted([logger.name for logger in all_loggers()]) + for logger_name in all_logger_names: - submenu.append( - MenuItem( - logger_name, - handler=functools.partial( - self.open_new_log_pane_for_logger, logger_name), - )) - return submenu + completions.append(( + logger_name, + functools.partial(self.open_new_log_pane_for_logger, + logger_name), + )) + return completions def _create_menu_items(self): themes_submenu = [ @@ -460,7 +487,7 @@ class ConsoleApp: '[File]', children=[ MenuItem('Open Logger', - children=self._create_logger_submenu()), + handler=self.open_command_runner_loggers), MenuItem( 'Log Table View', children=[ @@ -526,6 +553,11 @@ class ConsoleApp: MenuItem('Paste to Python Input', handler=self.repl_pane. paste_system_clipboard_to_input_buffer), + MenuItem('-'), + MenuItem('Copy all Python Output', + handler=self.repl_pane.copy_all_output_text), + MenuItem('Copy all Python Input', + handler=self.repl_pane.copy_all_input_text), ], ), ] @@ -629,7 +661,13 @@ class ConsoleApp: def focus_on_container(self, pane): """Set application focus to a specific container.""" - self.application.layout.focus(pane) + # Try to focus on the given pane + try: + self.application.layout.focus(pane) + except ValueError: + # If the container can't be focused, focus on the first visible + # window pane. + self.window_manager.focus_first_visible_pane() def toggle_light_theme(self): """Toggle light and dark theme colors.""" @@ -706,12 +744,6 @@ class ConsoleApp: asyncio.set_event_loop(self.user_code_loop) self.user_code_loop.run_forever() - def run_after_render_hooks(self, *unused_args, **unused_kwargs): - """Run each active pane's `after_render_hook` if defined.""" - for pane in self.window_manager.active_panes(): - if hasattr(pane, 'after_render_hook'): - pane.after_render_hook() - def start_user_code_thread(self): """Create a thread for running user code so the UI isn't blocked.""" thread = Thread(target=self._user_code_thread_entry, @@ -760,16 +792,24 @@ class ConsoleApp: """Return the currently focused window.""" return self.application.layout.current_window + def command_runner_is_open(self) -> bool: + return self.command_runner.show_dialog + + def command_runner_last_focused_pane(self) -> Any: + return self.command_runner.last_focused_pane + def modal_window_is_open(self): """Return true if any modal window or dialog is open.""" if self.app_help_text: return (self.app_help_window.show_window or self.keybind_help_window.show_window or self.user_guide_window.show_window - or self.quit_dialog.show_dialog) + or self.quit_dialog.show_dialog + or self.command_runner.show_dialog) return (self.keybind_help_window.show_window or self.user_guide_window.show_window - or self.quit_dialog.show_dialog) + or self.quit_dialog.show_dialog + or self.command_runner.show_dialog) def exit_console(self): """Quit the console prompt_toolkit application UI.""" @@ -787,22 +827,12 @@ class ConsoleApp: if test_mode: background_log_task = asyncio.create_task(self.log_forever()) - background_menu_updater_task = asyncio.create_task( - self.background_menu_updater()) try: unused_result = await self.application.run_async( set_exception_handler=True) finally: if test_mode: background_log_task.cancel() - background_menu_updater_task.cancel() - - async def background_menu_updater(self): - """Periodically update main menu items to capture new logger names.""" - while True: - await asyncio.sleep(30) - _LOG.debug('Update main menu items') - self.update_menu_items() async def log_forever(self): """Test mode async log generator coroutine that runs forever.""" diff --git a/pw_console/py/pw_console/console_prefs.py b/pw_console/py/pw_console/console_prefs.py index a7d1c7bce..70ac3bef3 100644 --- a/pw_console/py/pw_console/console_prefs.py +++ b/pw_console/py/pw_console/console_prefs.py @@ -15,7 +15,7 @@ import os from pathlib import Path -from typing import List, Union +from typing import Dict, List, Union from pw_console.style import get_theme_colors from pw_console.yaml_config_loader_mixin import YamlConfigLoaderMixin @@ -42,6 +42,13 @@ _DEFAULT_CONFIG = { # Window arrangement 'windows': {}, 'window_column_split_method': 'vertical', + 'command_runner': { + 'width': 80, + 'height': 10, + 'position': { + 'top': 3 + }, + }, } _DEFAULT_PROJECT_FILE = Path('$PW_PROJECT_ROOT/.pw_console.yaml') @@ -203,6 +210,24 @@ class ConsolePrefs(YamlConfigLoaderMixin): return list(column_type for column_type in self.windows.keys()) @property + def command_runner_position(self) -> Dict[str, int]: + position = self._config.get('command_runner', + {}).get('position', {'top': 3}) + return { + key: value + for key, value in position.items() + if key in ['top', 'bottom', 'left', 'right'] + } + + @property + def command_runner_width(self) -> int: + return self._config.get('command_runner', {}).get('width', 80) + + @property + def command_runner_height(self) -> int: + return self._config.get('command_runner', {}).get('height', 10) + + @property def unique_window_titles(self) -> set: titles = [] for window_list_title, column in self.windows.items(): diff --git a/pw_console/py/pw_console/docs/user_guide.rst b/pw_console/py/pw_console/docs/user_guide.rst index 67baef164..7e0f4eadf 100644 --- a/pw_console/py/pw_console/docs/user_guide.rst +++ b/pw_console/py/pw_console/docs/user_guide.rst @@ -5,7 +5,9 @@ User Guide .. seealso:: - This guide can be viewed online at: https://pigweed.dev/pw_console/ + This guide can be viewed online at: + https://pigweed.dev/pw_console/py/pw_console/docs/user_guide.html + The Pigweed Console provides a Python repl (read eval print loop) and log viewer in a single-window terminal based interface. @@ -27,9 +29,11 @@ There are a few ways to exit the Pigweed Console user interface: 1. Click the :guilabel:`[File]` menu and then :guilabel:`Exit`. 2. Type ``quit`` or ``exit`` in the Python Input window and press :kbd:`Enter`. 3. Press :kbd:`Ctrl-d` once to show the quit confirmation dialog. From there - pressing :kbd:`Ctrl-d` a second time or :kbd:`y` will exit. -4. Pressing :kbd:`Ctrl-x` quickly followed by :kbd:`Ctrl-c` will exit without + press :kbd:`Ctrl-d` a second time or :kbd:`y` will exit. +4. Press :kbd:`Ctrl-x` quickly followed by :kbd:`Ctrl-c` will exit without confirmation. +5. Press :kbd:`Ctrl-p` to search for commands, type ``exit``, then press + :kbd:`Enter`. Interface Layout @@ -64,8 +68,36 @@ mouse wheel should work too. This requires that your terminal is able to send mouse events. -Main Menu Navigation with the Keyboard -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Navigation with the Keyboard +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The main menu can be searched by pressing :kbd:`Ctrl-p`. This opens a fuzzy +search box containing all main menu item actions. + +Words separated by spaces are used to narrow down the match results. The order +each word is entered does not matter. + +.. figure:: /pw_console/images/command_runner_main_menu.svg + :alt: Main menu item search dialog. + +============================================ ===================== +Function Keys +============================================ ===================== +Open main menu search :kbd:`Ctrl-p` +Cancel search :kbd:`Ctrl-c` +Run selected item :kbd:`Enter` + +Select next item :kbd:`Tab` + :kbd:`Down` +Select previous item :kbd:`Shift-Tab` + :kbd:`Up` +============================================ ===================== + +Switching Focus +~~~~~~~~~~~~~~~ + +Clicking on any window will focus on it. Alternatively, the key bindings below +will switch focus. ============================================ ===================== Function Keys @@ -189,15 +221,13 @@ Here is a view of the search bar: :: - +-------------------------------------------------------------------------------+ - | Enter : Search Ctrl-Alt-f : Add Filter Ctrl-Alt-r : Clear Filters | - | Search Ctrl-t : Column:All Ctrl-v : [ ] Invert Ctrl-n : Matcher:REGEX | - | / | - +-------------------------------------------------------------------------------+ + +--------------------------------------------------------------------------+ + | Search Column:All Ctrl-t [ ] Invert Ctrl-v Matcher:REGEX Ctrl-n | + | / Search Enter Cancel Ctrl-c | + +--------------------------------------------------------------------------+ Across the top are various functions with keyboard shortcuts listed. Each of -these are clickable with the mouse. The second line shows configurable search -parameters. +these are clickable with the mouse. **Search Parameters** @@ -618,15 +648,14 @@ Example Config - metadata1 - metadata2 - # If True, any metadata field not listed above in 'column_order' will be hidden in table view. + # If True, any metadata field not listed above in 'column_order' + # will be hidden in table view. column_order_omit_unspecified_columns: False # Unique Colors for Column Values # Color format: 'bg:#BG-HEX #FG-HEX STYLE' # All parts are optional. # Empty strings will leave styling unchanged. - # See prompt_toolkit style format docs here: - # https://python-prompt-toolkit.readthedocs.io/en/latest/pages/advanced_topics/styling.html column_colors: # Column name time: @@ -670,7 +699,8 @@ Example Config # Second window column Split 2 tabbed: - # This is a duplicate of the existing 'Device Logs' window with a new title. + # This is a duplicate of the existing 'Device Logs' window. + # The title is 'NEW DEVICE' NEW DEVICE: duplicate_of: Device Logs # Log filters are defined here @@ -713,6 +743,17 @@ Example Config all: regex: 'Apple.*USB' + # Command Runner dialog size and position + command_runner: + width: 80 + height: 10 + position: + top: 3 # 3 lines below the top edge of the screen + # Alternatively one of these options can be used instead: + # bottom: 2 # 2 lines above the bottom edge of the screen + # left: 2 # 2 lines away from the left edge of the screen + # right: 2 # 2 lines away from the right edge of the screen + Known Issues ------------ @@ -721,7 +762,8 @@ Log Window ~~~~~~~~~~ - Tab character rendering will not work in the log pane view. They will - appear as ``^I`` since prompt_toolkit can't render them. See this issue for details: + appear as ``^I`` since prompt_toolkit can't render them. See this issue for + details: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/556 diff --git a/pw_console/py/pw_console/help_window.py b/pw_console/py/pw_console/help_window.py index 758a5f68f..ccb6d0302 100644 --- a/pw_console/py/pw_console/help_window.py +++ b/pw_console/py/pw_console/help_window.py @@ -203,9 +203,16 @@ class HelpWindow(ConditionalContainer): scrollbar_padding = 1 scrollbar_width = 1 - return self.max_line_length + (left_side_frame_and_padding_width + - right_side_frame_and_padding_width + - scrollbar_padding + scrollbar_width) + desired_width = self.max_line_length + ( + left_side_frame_and_padding_width + + right_side_frame_and_padding_width + scrollbar_padding + + scrollbar_width) + + window_manager_width = ( + self.application.window_manager.current_window_manager_width) + if not window_manager_width: + window_manager_width = 80 + return min(desired_width, window_manager_width) def load_user_guide(self): rstdoc = Path(__file__).parent / 'docs/user_guide.rst' diff --git a/pw_console/py/pw_console/key_bindings.py b/pw_console/py/pw_console/key_bindings.py index cec1f613b..22e053de5 100644 --- a/pw_console/py/pw_console/key_bindings.py +++ b/pw_console/py/pw_console/key_bindings.py @@ -48,6 +48,13 @@ def create_key_bindings(console_app): # F2 is ptpython settings # F3 is ptpython history + @bindings.add( + 'c-p', + filter=Condition(lambda: not console_app.modal_window_is_open())) + def show_command_runner(event): + """Open command runner window.""" + console_app.open_command_runner_main_menu() + @bindings.add('c-left') def app_focus_previous(event): """Move focus to the previous widget.""" diff --git a/pw_console/py/pw_console/log_pane.py b/pw_console/py/pw_console/log_pane.py index 79ca5026b..620dd29f6 100644 --- a/pw_console/py/pw_console/log_pane.py +++ b/pw_console/py/pw_console/log_pane.py @@ -466,7 +466,7 @@ class LogPane(WindowPane): else: self._pane_subtitle = self._pane_subtitle + ', ' + text - def pane_subtitle(self): + def pane_subtitle(self) -> str: if not self._pane_subtitle: return ', '.join(self.log_view.log_store.channel_counts.keys()) logger_names = self._pane_subtitle.split(', ') @@ -550,7 +550,7 @@ class LogPane(WindowPane): # Menu separator ('-', None), ( - 'Save a copy', + 'Save/Export a copy', self.start_saveas, ), ('-', None), @@ -585,7 +585,7 @@ class LogPane(WindowPane): ] if self.is_a_duplicate: options += [( - 'Remove pane', + 'Remove/Delete pane', functools.partial(self.application.window_manager.remove_pane, self), )] @@ -603,7 +603,7 @@ class LogPane(WindowPane): self.log_view.apply_filter, ), ( - 'Reset active filters', + 'Clear/Reset active filters', self.log_view.clear_filters, ), ] diff --git a/pw_console/py/pw_console/repl_pane.py b/pw_console/py/pw_console/repl_pane.py index 97a8078b8..08ef96cd0 100644 --- a/pw_console/py/pw_console/repl_pane.py +++ b/pw_console/py/pw_console/repl_pane.py @@ -277,7 +277,8 @@ class ReplPane(WindowPane): is_checkbox=True, checked=lambda: self.wrap_output_lines)) results_toolbar.add_button( - ToolbarButton('Ctrl-Alt-c', 'Copy All Output', self.copy_text)) + ToolbarButton('Ctrl-Alt-c', 'Copy All Output', + self.copy_all_output_text)) results_toolbar.add_button( ToolbarButton('Ctrl-c', 'Copy Selected Text', self.copy_output_selection)) @@ -297,11 +298,16 @@ class ReplPane(WindowPane): clipboard_data = self.pw_ptpython_repl.default_buffer.copy_selection() self.application.application.clipboard.set_data(clipboard_data) - def copy_text(self): - """Copy visible text in this window pane to the system clipboard.""" + def copy_all_output_text(self): + """Copy all text in the Python output to the system clipboard.""" self.application.application.clipboard.set_text( self.output_field.buffer.text) + def copy_all_input_text(self): + """Copy all text in the Python input to the system clipboard.""" + self.application.application.clipboard.set_text( + self.pw_ptpython_repl.default_buffer.text) + # pylint: disable=no-self-use def get_all_key_bindings(self) -> List: """Return all keybinds for this plugin.""" @@ -320,9 +326,6 @@ class ReplPane(WindowPane): def get_all_menu_options(self): return [] - def after_render_hook(self): - """Run tasks after the last UI render.""" - def run_code(self): """Trigger a repl code execution on mouse click.""" self.pw_ptpython_repl.default_buffer.validate_and_handle() diff --git a/pw_console/py/pw_console/search_toolbar.py b/pw_console/py/pw_console/search_toolbar.py index e0d681c4a..2307a3c61 100644 --- a/pw_console/py/pw_console/search_toolbar.py +++ b/pw_console/py/pw_console/search_toolbar.py @@ -57,7 +57,6 @@ class SearchToolbar(ConditionalContainer): self._search_invert = False self._search_field = None - # FormattedText of the search column headers. self.input_field = TextArea( prompt=[ ('class:search-bar-setting', '/', diff --git a/pw_console/py/pw_console/style.py b/pw_console/py/pw_console/style.py index 8a0b486c1..19d41820d 100644 --- a/pw_console/py/pw_console/style.py +++ b/pw_console/py/pw_console/style.py @@ -16,6 +16,8 @@ import logging from dataclasses import dataclass +from prompt_toolkit.formatted_text import StyleAndTextTuples +from prompt_toolkit.formatted_text.base import OneStyleAndTextTuple from prompt_toolkit.styles import Style from prompt_toolkit.filters import has_focus @@ -211,7 +213,7 @@ _THEME_NAME_MAPPING = { 'dark': DarkColors(), 'high-contrast-dark': HighContrastDarkColors(), 'ansi': AnsiTerm(), -} # yapf: disable +} # yapf: disable def get_theme_colors(theme_name=''): @@ -373,6 +375,20 @@ def generate_styles(theme_name='dark'): 'quit-dialog-border': 'bg:{} {}'.format(theme.inactive_bg, theme.red_accent), + 'command-runner': 'bg:{}'.format(theme.inactive_bg), + 'command-runner-title': 'bg:{} {}'.format(theme.inactive_bg, + theme.default_fg), + 'command-runner-setting': '{}'.format(theme.purple_accent), + 'command-runner-border': 'bg:{} {}'.format(theme.inactive_bg, + theme.purple_accent), + 'command-runner-selected-item': 'bg:{}'.format(theme.selected_line_bg), + 'command-runner-fuzzy-highlight-0': '{}'.format(theme.blue_accent), + 'command-runner-fuzzy-highlight-1': '{}'.format(theme.cyan_accent), + 'command-runner-fuzzy-highlight-2': '{}'.format(theme.green_accent), + 'command-runner-fuzzy-highlight-3': '{}'.format(theme.yellow_accent), + 'command-runner-fuzzy-highlight-4': '{}'.format(theme.orange_accent), + 'command-runner-fuzzy-highlight-5': '{}'.format(theme.red_accent), + # Progress Bar Styles # Entire set of ProgressBars - no title is used in pw_console 'title': '', @@ -427,7 +443,7 @@ def generate_styles(theme_name='dark'): 'theme-bg-button-active': 'bg:{}'.format(theme.button_active_bg), 'theme-bg-button-inactive': 'bg:{}'.format(theme.button_inactive_bg), - } # yapf: disable + } # yapf: disable return Style.from_dict(pw_console_styles) @@ -456,8 +472,14 @@ def get_pane_style(pt_container) -> str: def get_pane_indicator(pt_container, title, mouse_handler=None, - hide_indicator=False): + hide_indicator=False) -> StyleAndTextTuples: """Return formatted text for a pane indicator and title.""" + + inactive_indicator: OneStyleAndTextTuple + active_indicator: OneStyleAndTextTuple + inactive_title: OneStyleAndTextTuple + active_title: OneStyleAndTextTuple + if mouse_handler: inactive_indicator = ('class:pane_indicator_inactive', ' ', mouse_handler) @@ -470,7 +492,7 @@ def get_pane_indicator(pt_container, inactive_title = ('class:pane_title_inactive', title) active_title = ('class:pane_title_active', title) - fragments = [] + fragments: StyleAndTextTuples = [] if has_focus(pt_container.__pt_container__())(): if not hide_indicator: fragments.append(active_indicator) diff --git a/pw_console/py/pw_console/widgets/border.py b/pw_console/py/pw_console/widgets/border.py index d4624e9c9..64a03a3be 100644 --- a/pw_console/py/pw_console/widgets/border.py +++ b/pw_console/py/pw_console/widgets/border.py @@ -13,10 +13,11 @@ # the License. """Wrapper fuctions to add borders around prompt_toolkit containers.""" -from typing import List +from typing import List, Optional from prompt_toolkit.layout import ( AnyContainer, + FormattedTextControl, HSplit, VSplit, Window, @@ -26,7 +27,8 @@ from prompt_toolkit.layout import ( def create_border( # pylint: disable=too-many-arguments content: AnyContainer, - content_height: int, + content_height: Optional[int] = None, + title: str = '', border_style: str = '', base_style: str = '', top: bool = True, @@ -48,9 +50,17 @@ def create_border( if left: top_border_items.append( Window(width=1, height=1, char=top_left_char, style=border_style)) + + title_text = None + if title: + title_text = FormattedTextControl([ + ('', f'{horizontal_char}{horizontal_char} {title} ') + ]) + top_border_items.append( Window( - char='━', + title_text, + char=horizontal_char, # Expand width to max available space dont_extend_width=False, style=border_style)) diff --git a/pw_console/py/pw_console/widgets/window_pane.py b/pw_console/py/pw_console/widgets/window_pane.py index eb16428cf..ab2484a74 100644 --- a/pw_console/py/pw_console/widgets/window_pane.py +++ b/pw_console/py/pw_console/widgets/window_pane.py @@ -21,9 +21,11 @@ from prompt_toolkit.layout.dimension import AnyDimension from prompt_toolkit.filters import Condition from prompt_toolkit.layout import ( + AnyContainer, ConditionalContainer, Dimension, HSplit, + walk, ) from pw_console.get_pw_console_app import get_pw_console_app @@ -199,3 +201,11 @@ class WindowPane(ABC): style=functools.partial(pw_console.style.get_pane_style, self), ), filter=Condition(lambda: self.show_pane)) + + def has_child_container(self, child_container: AnyContainer) -> bool: + if not child_container: + return False + for container in walk(self.__pt_container__()): + if container == child_container: + return True + return False diff --git a/pw_console/py/pw_console/widgets/window_pane_toolbar.py b/pw_console/py/pw_console/widgets/window_pane_toolbar.py index 76ee0fc11..3c16beb62 100644 --- a/pw_console/py/pw_console/widgets/window_pane_toolbar.py +++ b/pw_console/py/pw_console/widgets/window_pane_toolbar.py @@ -66,9 +66,13 @@ class WindowPaneToolbar: def get_left_text_tokens(self): """Return toolbar indicator and title.""" - title = ' {} '.format(self.title) + title = self.title + if not title and self.parent_window_pane: + # No title was set, fetch the parent window pane title if available. + parent_pane_title = self.parent_window_pane.pane_title() + title = parent_pane_title if parent_pane_title else title return pw_console.style.get_pane_indicator(self.focus_check_container, - title, + f' {title} ', self.focus_mouse_handler) def get_center_text_tokens(self): @@ -161,8 +165,6 @@ class WindowPaneToolbar: # Set parent_window_pane related options if self.parent_window_pane: - if not title: - self.title = self.parent_window_pane.pane_title() if not subtitle: self.subtitle = self.parent_window_pane.pane_subtitle self.focus_check_container = self.parent_window_pane diff --git a/pw_console/py/pw_console/window_list.py b/pw_console/py/pw_console/window_list.py index 075f4dbba..ec21b5810 100644 --- a/pw_console/py/pw_console/window_list.py +++ b/pw_console/py/pw_console/window_list.py @@ -203,8 +203,21 @@ class WindowList: def get_current_active_pane(self): """Return the current active window pane.""" focused_pane = None + + command_runner_focused_pane = None + if self.application.command_runner_is_open(): + command_runner_focused_pane = ( + self.application.command_runner_last_focused_pane()) + for index, pane in enumerate(self.active_panes): + in_focus = False if has_focus(pane)(): + in_focus = True + elif command_runner_focused_pane and pane.has_child_container( + command_runner_focused_pane): + in_focus = True + + if in_focus: focused_pane = pane self.focused_pane_index = index break diff --git a/pw_console/py/pw_console/window_manager.py b/pw_console/py/pw_console/window_manager.py index a6dc4ea59..6b880532f 100644 --- a/pw_console/py/pw_console/window_manager.py +++ b/pw_console/py/pw_console/window_manager.py @@ -690,7 +690,7 @@ class WindowManager: """Focus on the first visible container.""" for pane in self.active_panes(): if pane.show_pane: - self.application.focus_on_container(pane) + self.application.application.layout.focus(pane) break def check_for_all_hidden_panes_and_unhide(self) -> None: @@ -1000,13 +1000,13 @@ class WindowManager: )) menu_items.extend( MenuItem( - '{index}: {title} {subtitle}'.format( + '{index}: {title}'.format( index=pane_index + 1, title=pane.menu_title(), - subtitle=pane.pane_subtitle()), + ), children=[ MenuItem( - '{check} Show Window'.format( + '{check} Show/Hide Window'.format( check=pw_console.widgets.checkbox. to_checkbox_text(pane.show_pane, end='')), handler=functools.partial(self.toggle_pane, pane), diff --git a/pw_console/py/window_manager_test.py b/pw_console/py/window_manager_test.py index 0193af52e..676d07cb4 100644 --- a/pw_console/py/window_manager_test.py +++ b/pw_console/py/window_manager_test.py @@ -98,14 +98,14 @@ def _window_pane_counts(window_manager): ] -def _window_pane_titles(window_manager): +def window_pane_titles(window_manager): return [[ pane.pane_title() + ' - ' + pane.pane_subtitle() for pane in window_list.active_panes ] for window_list in window_manager.window_lists] -def _target_list_and_pane(window_manager, list_index, pane_index): +def target_list_and_pane(window_manager, list_index, pane_index): # pylint: disable=protected-access # Bypass prompt_toolkit has_focus() window_manager._get_active_window_list_and_pane = ( @@ -132,23 +132,23 @@ class TestWindowManager(unittest.TestCase): self.assertEqual([4], _window_pane_counts(window_manager)) # Move 2 windows to the right into their own splits - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 1, 0) + target_list_and_pane(window_manager, 1, 0) window_manager.move_pane_right() # 3 splits, first split has 2 windows self.assertEqual([2, 1, 1], _window_pane_counts(window_manager)) # Move the first window in the first split left - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_left() # 4 splits, each with their own window self.assertEqual([1, 1, 1, 1], _window_pane_counts(window_manager)) # Move the first window to the right - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() # 3 splits, first split has 2 windows self.assertEqual([2, 1, 1], _window_pane_counts(window_manager)) @@ -171,7 +171,7 @@ class TestWindowManager(unittest.TestCase): window_manager = console_app.window_manager - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) # Should have one window list split of size 50. self.assertEqual( _window_list_widths(window_manager), @@ -188,11 +188,11 @@ class TestWindowManager(unittest.TestCase): # Move another pane to the right twice, creating a third # window_list split. - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() # Above window pane is at a new location - _target_list_and_pane(window_manager, 1, 0) + target_list_and_pane(window_manager, 1, 0) window_manager.move_pane_right() # Should have 3 splits now @@ -209,7 +209,7 @@ class TestWindowManager(unittest.TestCase): self.assertEqual(len(list(window_manager.active_panes())), 4) # Target the middle split - _target_list_and_pane(window_manager, 1, 0) + target_list_and_pane(window_manager, 1, 0) # Shrink the middle split twice window_manager.shrink_split() window_manager.shrink_split() @@ -225,7 +225,7 @@ class TestWindowManager(unittest.TestCase): ) # Target the first split - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.reset_split_sizes() # Shrink the first split twice window_manager.shrink_split() @@ -241,7 +241,7 @@ class TestWindowManager(unittest.TestCase): ) # Target the third (last) split - _target_list_and_pane(window_manager, 2, 0) + target_list_and_pane(window_manager, 2, 0) window_manager.reset_split_sizes() # Shrink the third split once window_manager.shrink_split() @@ -273,7 +273,7 @@ class TestWindowManager(unittest.TestCase): ) # Target the middle split - _target_list_and_pane(window_manager, 1, 0) + target_list_and_pane(window_manager, 1, 0) # Move the middle window pane left window_manager.move_pane_left() # This is called on the next render pass @@ -405,7 +405,7 @@ class TestWindowManager(unittest.TestCase): # Check window pane ordering self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log2 - test_log2', @@ -419,7 +419,7 @@ class TestWindowManager(unittest.TestCase): target_window_pane(0) window_manager.move_pane_down() self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log1 - test_log1', @@ -434,7 +434,7 @@ class TestWindowManager(unittest.TestCase): target_window_pane(1) window_manager.move_pane_up() self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log0 - test_log0', @@ -447,7 +447,7 @@ class TestWindowManager(unittest.TestCase): target_window_pane(0) window_manager.move_pane_up() self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log0 - test_log0', @@ -465,7 +465,7 @@ class TestWindowManager(unittest.TestCase): window_manager = console_app.window_manager self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log3 - test_log3', @@ -480,7 +480,7 @@ class TestWindowManager(unittest.TestCase): # Scenario: Move between panes with a single stacked window list. # Set the first pane in focus. - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) # Switch focus to the next pane window_manager.focus_next_pane() # Pane index 1 should now be focused. @@ -489,7 +489,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set the first pane in focus. - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) # Switch focus to the previous pane window_manager.focus_previous_pane() # Previous pane should wrap around to the last pane in the first @@ -499,7 +499,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set the last pane in focus. - _target_list_and_pane(window_manager, 0, 4) + target_list_and_pane(window_manager, 0, 4) # Switch focus to the next pane window_manager.focus_next_pane() # Next pane should wrap around to the first pane in the first @@ -520,7 +520,7 @@ class TestWindowManager(unittest.TestCase): wraps=window_manager.window_lists[0].switch_to_tab) # Set the first pane/tab in focus. - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) # Switch focus to the next pane/tab window_manager.focus_next_pane() # Check switch_to_tab is called @@ -533,7 +533,7 @@ class TestWindowManager(unittest.TestCase): window_manager.window_lists[0].switch_to_tab.reset_mock() # Set the last pane/tab in focus. - _target_list_and_pane(window_manager, 0, 4) + target_list_and_pane(window_manager, 0, 4) # Switch focus to the next pane/tab window_manager.focus_next_pane() # Check switch_to_tab is called @@ -546,7 +546,7 @@ class TestWindowManager(unittest.TestCase): window_manager.window_lists[0].switch_to_tab.reset_mock() # Set the first pane/tab in focus. - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) # Switch focus to the prev pane/tab window_manager.focus_previous_pane() # Check switch_to_tab is called @@ -563,12 +563,12 @@ class TestWindowManager(unittest.TestCase): # Setup: Move two panes to the right into their own stacked # window_list. - _target_list_and_pane(window_manager, 0, 4) + target_list_and_pane(window_manager, 0, 4) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 0, 3) + target_list_and_pane(window_manager, 0, 3) window_manager.move_pane_right() self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log3 - test_log3', @@ -587,7 +587,7 @@ class TestWindowManager(unittest.TestCase): wraps=window_manager.window_lists[1].switch_to_tab) # Set Log1 in focus - _target_list_and_pane(window_manager, 0, 2) + target_list_and_pane(window_manager, 0, 2) window_manager.focus_next_pane() # Log0 should now have focus console_app.focus_on_container.assert_called_once_with( @@ -595,7 +595,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set Log0 in focus - _target_list_and_pane(window_manager, 1, 0) + target_list_and_pane(window_manager, 1, 0) window_manager.focus_previous_pane() # Log1 should now have focus console_app.focus_on_container.assert_called_once_with( @@ -609,7 +609,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set Python Repl in focus - _target_list_and_pane(window_manager, 1, 1) + target_list_and_pane(window_manager, 1, 1) window_manager.focus_next_pane() # Log3 should now have focus console_app.focus_on_container.assert_called_once_with( @@ -621,7 +621,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set Log3 in focus - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.focus_next_pane() # Log2 should now have focus console_app.focus_on_container.assert_called_once_with( @@ -633,7 +633,7 @@ class TestWindowManager(unittest.TestCase): console_app.focus_on_container.reset_mock() # Set Python Repl in focus - _target_list_and_pane(window_manager, 1, 1) + target_list_and_pane(window_manager, 1, 1) window_manager.focus_previous_pane() # Log0 should now have focus console_app.focus_on_container.assert_called_once_with( @@ -660,16 +660,16 @@ class TestWindowManager(unittest.TestCase): self.assertTrue(window_manager.vertical_window_list_spliting()) # Move windows to create 3 splits - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 1, 1) + target_list_and_pane(window_manager, 1, 1) window_manager.move_pane_right() # Check windows are where expected self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log1 - test_log1', @@ -738,16 +738,16 @@ class TestWindowManager(unittest.TestCase): window_manager.create_root_container() # Move windows to create 3 splits - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 0, 0) + target_list_and_pane(window_manager, 0, 0) window_manager.move_pane_right() - _target_list_and_pane(window_manager, 1, 1) + target_list_and_pane(window_manager, 1, 1) window_manager.move_pane_right() # Check windows are where expected self.assertEqual( - _window_pane_titles(window_manager), + window_pane_titles(window_manager), [ [ 'Log1 - test_log1', |