diff options
385 files changed, 14478 insertions, 6034 deletions
diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs index 095a6ca1ed..3717876356 100644 --- a/.settings/org.eclipse.jdt.ui.prefs +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -17,10 +17,12 @@ sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_functional_interfaces=false sp_cleanup.convert_to_enhanced_for_loop=false sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=true sp_cleanup.format_source_code_changes_only=false +sp_cleanup.insert_inferred_type_arguments=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true @@ -36,7 +38,8 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class= sp_cleanup.qualify_static_member_accesses_with_declaring_class=false sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_redundant_type_arguments=false +sp_cleanup.remove_trailing_whitespaces=false sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true @@ -49,10 +52,13 @@ sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false +sp_cleanup.use_anonymous_class_creation=false sp_cleanup.use_blocks=true sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_lambda=false sp_cleanup.use_parentheses_in_expressions=false sp_cleanup.use_this_for_non_static_field_access=true sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=true sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_type_arguments=false @@ -25,7 +25,9 @@ Cloning the project repositories The Vaadin repository can be cloned using <pre><code>git clone https://github.com/vaadin/vaadin.git</code></pre> -or using your favorite Git tool +or using your favorite Git tool. + +If using Windows, you might want to add these Git settings: core.autocrlf=false and core.fileMode=false. Setting up Eclipse to Develop Vaadin 7 ========= diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss index 0a493e0356..77248c0c96 100644 --- a/WebContent/VAADIN/themes/base/common/common.scss +++ b/WebContent/VAADIN/themes/base/common/common.scss @@ -146,6 +146,12 @@ body &.v-app .v-app-loading { border: 0; margin: 0; } + +.v-contextmenu .gwt-MenuBar { + overflow-y: auto; + overflow-x: hidden; +} + .v-contextmenu .gwt-MenuItem div { cursor: pointer; vertical-align: middle; diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot Binary files differindex 7c79c6a6bc..6cfd566095 100644..100755 --- a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg index 45fdf33830..a9f8469503 100644..100755 --- a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg @@ -14,10 +14,11 @@ <glyph unicode="®" horiz-adv-x="1792" /> <glyph unicode="´" horiz-adv-x="1792" /> <glyph unicode="Æ" horiz-adv-x="1792" /> +<glyph unicode="Ø" horiz-adv-x="1792" /> <glyph unicode=" " horiz-adv-x="768" /> -<glyph unicode=" " /> +<glyph unicode=" " horiz-adv-x="1537" /> <glyph unicode=" " horiz-adv-x="768" /> -<glyph unicode=" " /> +<glyph unicode=" " horiz-adv-x="1537" /> <glyph unicode=" " horiz-adv-x="512" /> <glyph unicode=" " horiz-adv-x="384" /> <glyph unicode=" " horiz-adv-x="256" /> @@ -30,385 +31,474 @@ <glyph unicode="™" horiz-adv-x="1792" /> <glyph unicode="∞" horiz-adv-x="1792" /> <glyph unicode="≠" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="500" d="M0 0z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> -<glyph unicode="" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " /> -<glyph unicode="" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280zM768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z " /> -<glyph unicode="" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> -<glyph unicode="" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" /> -<glyph unicode="" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> -<glyph unicode="" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" /> -<glyph unicode="" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> -<glyph unicode="" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> -<glyph unicode="" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> -<glyph unicode="" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> -<glyph unicode="" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M725 977l-170 -450q73 -1 153.5 -2t119 -1.5t52.5 -0.5l29 2q-32 95 -92 241q-53 132 -92 211zM21 -128h-21l2 79q22 7 80 18q89 16 110 31q20 16 48 68l237 616l280 724h75h53l11 -21l205 -480q103 -242 124 -297q39 -102 96 -235q26 -58 65 -164q24 -67 65 -149 q22 -49 35 -57q22 -19 69 -23q47 -6 103 -27q6 -39 6 -57q0 -14 -1 -26q-80 0 -192 8q-93 8 -189 8q-79 0 -135 -2l-200 -11l-58 -2q0 45 4 78l131 28q56 13 68 23q12 12 12 27t-6 32l-47 114l-92 228l-450 2q-29 -65 -104 -274q-23 -64 -23 -84q0 -31 17 -43 q26 -21 103 -32q3 0 13.5 -2t30 -5t40.5 -6q1 -28 1 -58q0 -17 -2 -27q-66 0 -349 20l-48 -8q-81 -14 -167 -14z" /> -<glyph unicode="" horiz-adv-x="1408" d="M555 15q76 -32 140 -32q131 0 216 41t122 113q38 70 38 181q0 114 -41 180q-58 94 -141 126q-80 32 -247 32q-74 0 -101 -10v-144l-1 -173l3 -270q0 -15 12 -44zM541 761q43 -7 109 -7q175 0 264 65t89 224q0 112 -85 187q-84 75 -255 75q-52 0 -130 -13q0 -44 2 -77 q7 -122 6 -279l-1 -98q0 -43 1 -77zM0 -128l2 94q45 9 68 12q77 12 123 31q17 27 21 51q9 66 9 194l-2 497q-5 256 -9 404q-1 87 -11 109q-1 4 -12 12q-18 12 -69 15q-30 2 -114 13l-4 83l260 6l380 13l45 1q5 0 14 0.5t14 0.5q1 0 21.5 -0.5t40.5 -0.5h74q88 0 191 -27 q43 -13 96 -39q57 -29 102 -76q44 -47 65 -104t21 -122q0 -70 -32 -128t-95 -105q-26 -20 -150 -77q177 -41 267 -146q92 -106 92 -236q0 -76 -29 -161q-21 -62 -71 -117q-66 -72 -140 -108q-73 -36 -203 -60q-82 -15 -198 -11l-197 4q-84 2 -298 -11q-33 -3 -272 -11z" /> -<glyph unicode="" horiz-adv-x="1024" d="M0 -126l17 85q4 1 77 20q76 19 116 39q29 37 41 101l27 139l56 268l12 64q8 44 17 84.5t16 67t12.5 46.5t9 30.5t3.5 11.5l29 157l16 63l22 135l8 50v38q-41 22 -144 28q-28 2 -38 4l19 103l317 -14q39 -2 73 -2q66 0 214 9q33 2 68 4.5t36 2.5q-2 -19 -6 -38 q-7 -29 -13 -51q-55 -19 -109 -31q-64 -16 -101 -31q-12 -31 -24 -88q-9 -44 -13 -82q-44 -199 -66 -306l-61 -311l-38 -158l-43 -235l-12 -45q-2 -7 1 -27q64 -15 119 -21q36 -5 66 -10q-1 -29 -7 -58q-7 -31 -9 -41q-18 0 -23 -1q-24 -2 -42 -2q-9 0 -28 3q-19 4 -145 17 l-198 2q-41 1 -174 -11q-74 -7 -98 -9z" /> -<glyph unicode="" horiz-adv-x="1792" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l215 -1h293l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -42.5 2t-103.5 -1t-111 -1 q-34 0 -67 -5q-10 -97 -8 -136l1 -152v-332l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-88 0 -233 -14q-48 -4 -70 -4q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q8 192 6 433l-5 428q-1 62 -0.5 118.5t0.5 102.5t-2 57t-6 15q-6 5 -14 6q-38 6 -148 6q-43 0 -100 -13.5t-73 -24.5q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1744 128q33 0 42 -18.5t-11 -44.5 l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80z" /> -<glyph unicode="" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l446 -1h318l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -58.5 2t-138.5 -1t-128 -1 q-94 0 -127 -5q-10 -97 -8 -136l1 -152v52l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-82 0 -233 -13q-45 -5 -70 -5q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q6 137 6 433l-5 44q0 265 -2 278q-2 11 -6 15q-6 5 -14 6q-38 6 -148 6q-50 0 -168.5 -14t-132.5 -24q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1505 113q26 -20 26 -49t-26 -49l-162 -126 q-26 -20 -44.5 -11t-18.5 42v80h-1024v-80q0 -33 -18.5 -42t-44.5 11l-162 126q-26 20 -26 49t26 49l162 126q26 20 44.5 11t18.5 -42v-80h1024v80q0 33 18.5 42t44.5 -11z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" /> -<glyph unicode="" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> -<glyph unicode="" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" /> -<glyph unicode="" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> -<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" /> -<glyph unicode="" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" /> -<glyph unicode="" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" /> -<glyph unicode="" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> -<glyph unicode="" horiz-adv-x="1152" d="M742 -37l-652 651q-37 37 -37 90.5t37 90.5l652 651q37 37 90.5 37t90.5 -37l75 -75q37 -37 37 -90.5t-37 -90.5l-486 -486l486 -485q37 -38 37 -91t-37 -90l-75 -75q-37 -37 -90.5 -37t-90.5 37z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1099 704q0 -52 -37 -91l-652 -651q-37 -37 -90 -37t-90 37l-76 75q-37 39 -37 91q0 53 37 90l486 486l-486 485q-37 39 -37 91q0 53 37 90l76 75q36 38 90 38t90 -38l652 -651q37 -37 37 -90z" /> -<glyph unicode="" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" /> -<glyph unicode="" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> -<glyph unicode="" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" /> -<glyph unicode="" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> -<glyph unicode="" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" /> -<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> -<glyph unicode="" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> -<glyph unicode="" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> -<glyph unicode="" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> -<glyph unicode="" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 320q0 -53 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-486 485l-486 -485q-36 -38 -90 -38t-90 38l-75 75q-38 36 -38 90q0 53 38 91l651 651q37 37 90 37q52 0 91 -37l650 -651q38 -38 38 -91z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 832q0 -53 -37 -90l-651 -651q-38 -38 -91 -38q-54 0 -90 38l-651 651q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l486 -486l486 486q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " /> -<glyph unicode="" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1920" d="M512 512v-384h-256v384h256zM896 1024v-896h-256v896h256zM1280 768v-640h-256v640h256zM1664 1152v-1024h-256v1024h256zM1792 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5z M1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1307 618l23 219h-198v109q0 49 15.5 68.5t71.5 19.5h110v219h-175q-152 0 -218 -72t-66 -213v-131h-131v-219h131v-635h262v635h175zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> -<glyph unicode="" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> -<glyph unicode="" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" /> -<glyph unicode="" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" /> -<glyph unicode="" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> -<glyph unicode="" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> -<glyph unicode="" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> -<glyph unicode="" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> -<glyph unicode="" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> -<glyph unicode="" horiz-adv-x="768" d="M511 980h257l-30 -284h-227v-824h-341v824h-170v284h170v171q0 182 86 275.5t283 93.5h227v-284h-142q-39 0 -62.5 -6.5t-34 -23.5t-13.5 -34.5t-3 -49.5v-142z" /> -<glyph unicode="" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" /> -<glyph unicode="" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> -<glyph unicode="" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM1664 128q0 -52 -38 -90t-90 -38 h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" /> -<glyph unicode="" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" /> -<glyph unicode="" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> -<glyph unicode="" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" /> -<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" /> -<glyph unicode="" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> -<glyph unicode="" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " /> -<glyph unicode="" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " /> -<glyph unicode="" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> -<glyph unicode="" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" /> -<glyph unicode="" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> -<glyph unicode="" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> -<glyph unicode="" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> -<glyph unicode="" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> -<glyph unicode="" d="M678 -57q0 -38 -10 -71h-380q-95 0 -171.5 56.5t-103.5 147.5q24 45 69 77.5t100 49.5t107 24t107 7q32 0 49 -2q6 -4 30.5 -21t33 -23t31 -23t32 -25.5t27.5 -25.5t26.5 -29.5t21 -30.5t17.5 -34.5t9.5 -36t4.5 -40.5zM385 294q-234 -7 -385 -85v433q103 -118 273 -118 q32 0 70 5q-21 -61 -21 -86q0 -67 63 -149zM558 805q0 -100 -43.5 -160.5t-140.5 -60.5q-51 0 -97 26t-78 67.5t-56 93.5t-35.5 104t-11.5 99q0 96 51.5 165t144.5 69q66 0 119 -41t84 -104t47 -130t16 -128zM1536 896v-736q0 -119 -84.5 -203.5t-203.5 -84.5h-468 q39 73 39 157q0 66 -22 122.5t-55.5 93t-72 71t-72 59.5t-55.5 54.5t-22 59.5q0 36 23 68t56 61.5t65.5 64.5t55.5 93t23 131t-26.5 145.5t-75.5 118.5q-6 6 -14 11t-12.5 7.5t-10 9.5t-10.5 17h135l135 64h-437q-138 0 -244.5 -38.5t-182.5 -133.5q0 126 81 213t207 87h960 q119 0 203.5 -84.5t84.5 -203.5v-96h-256v256h-128v-256h-256v-128h256v-256h128v256h256z" /> -<glyph unicode="" horiz-adv-x="1664" d="M876 71q0 21 -4.5 40.5t-9.5 36t-17.5 34.5t-21 30.5t-26.5 29.5t-27.5 25.5t-32 25.5t-31 23t-33 23t-30.5 21q-17 2 -50 2q-54 0 -106 -7t-108 -25t-98 -46t-69 -75t-27 -107q0 -68 35.5 -121.5t93 -84t120.5 -45.5t127 -15q59 0 112.5 12.5t100.5 39t74.5 73.5 t27.5 110zM756 933q0 60 -16.5 127.5t-47 130.5t-84 104t-119.5 41q-93 0 -144 -69t-51 -165q0 -47 11.5 -99t35.5 -104t56 -93.5t78 -67.5t97 -26q97 0 140.5 60.5t43.5 160.5zM625 1408h437l-135 -79h-135q71 -45 110 -126t39 -169q0 -74 -23 -131.5t-56 -92.5t-66 -64.5 t-56 -61t-23 -67.5q0 -26 16.5 -51t43 -48t58.5 -48t64 -55.5t58.5 -66t43 -85t16.5 -106.5q0 -160 -140 -282q-152 -131 -420 -131q-59 0 -119.5 10t-122 33.5t-108.5 58t-77 89t-30 121.5q0 61 37 135q32 64 96 110.5t145 71t155 36t150 13.5q-64 83 -64 149q0 12 2 23.5 t5 19.5t8 21.5t7 21.5q-40 -5 -70 -5q-149 0 -255.5 98t-106.5 246q0 140 95 250.5t234 141.5q94 20 187 20zM1664 1152v-128h-256v-256h-128v256h-256v128h256v256h128v-256h256z" /> -<glyph unicode="" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> -<glyph unicode="" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> -<glyph unicode="" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> -<glyph unicode="" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" /> -<glyph unicode="" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> -<glyph unicode="" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" /> -<glyph unicode="" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1664 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5 q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1024 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1024 608v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280z M768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> -<glyph unicode="" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> -<glyph unicode="" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> -<glyph unicode="" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" /> -<glyph unicode="" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " /> +<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" /> +<glyph unicode="" horiz-adv-x="1792" d="M93 1350q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78z" /> +<glyph unicode="" d="M0 -64q0 50 34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5 q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 32v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5 t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768zM128 1120q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317 q54 43 100.5 115.5t46.5 131.5v11v13.5t-0.5 13t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z " /> +<glyph unicode="" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354 q-25 27 -25 48zM221 829l306 -297l-73 -421l378 199l377 -199l-72 421l306 297l-422 62l-189 382l-189 -382z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 131q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5 h-874q-121 0 -194 69.5t-73 189.5zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 -96v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 64v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM128 320q0 -26 19 -45t45 -19h128 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM128 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19 h-128q-26 0 -45 -19t-19 -45v-128zM512 -64q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM512 704q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512zM1536 64 v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45zM1536 320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 704q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128zM1536 1088q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 128v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM0 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 128v384q0 52 38 90t90 38h512q52 0 90 -38 t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM896 896v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 608v192 q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1280 1120v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 96v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 96v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM640 608v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68zM640 1120v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M121 608q0 40 28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68z" /> +<glyph unicode="" horiz-adv-x="1408" d="M110 214q0 40 28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68t-28 -68l-294 -294l294 -294q28 -28 28 -68t-28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294 q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 704q0 143 55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90t-37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5z M256 704q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM384 672v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" d="M0 640q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181 q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298zM640 768v640q0 52 38 90t90 38t90 -38t38 -90v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 -96v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM384 -96v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM768 -96v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-576 q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 -96v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1536 -96v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23z" /> +<glyph unicode="" d="M0 531v222q0 12 8 23t19 13l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10 q129 -119 165 -170q7 -8 7 -22q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108 q-44 -23 -91 -38q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5z M512 640q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 1056v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23zM256 76q0 -22 7 -40.5 t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5v948h-896v-948zM384 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM640 224v576q0 14 9 23t23 9h64 q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23zM896 224v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1664" d="M26 636.5q1 13.5 11 21.5l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5zM256 64 v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22 v-376z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 544v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M50 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256 q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73zM809 540q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 96v320q0 40 28 68t68 28h465l135 -136q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 985q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39q17 -41 -14 -70 l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70zM1152 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM418 620q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM416 672q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23z" /> +<glyph unicode="" d="M0 64v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552q25 -61 25 -123v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM197 576h316l95 -192h320l95 192h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8 t-2.5 -8z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 320v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55t-32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56z" /> +<glyph unicode="" d="M0 640q0 156 61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5 t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298z" /> +<glyph unicode="" d="M0 0v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129 q-19 -19 -45 -19t-45 19t-19 45zM18 800v7q65 268 270 434.5t480 166.5q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179 q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 160v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832z M256 288v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 544v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z M256 800v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 288v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z M512 544v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5zM512 800v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5z " /> +<glyph unicode="" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68zM320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110zM320 320v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19 q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 650q0 151 67 291t179 242.5t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32 q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32 q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314z" /> +<glyph unicode="" horiz-adv-x="768" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 448v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45zM908 464q0 21 12 35.5t29 25t34 23t29 35.5t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5 q15 0 25 -5q70 -27 112.5 -93t42.5 -142t-42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5zM1008 228q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5 q140 -59 225 -188.5t85 -282.5t-85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45zM1109 -7q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19 q13 0 26 -5q211 -91 338 -283.5t127 -422.5t-127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 0v640h640v-640h-640zM0 768v640h640v-640h-640zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM256 256v128h128v-128h-128zM256 1024v128h128v-128h-128zM768 0v640h384v-128h128v128h128v-384h-384v128h-128v-384h-128zM768 768v640h640v-640h-640z M896 896h384v384h-384v-384zM1024 0v128h128v-128h-128zM1024 1024v128h128v-128h-128zM1280 0v128h128v-128h-128z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 0v1408h63v-1408h-63zM94 1v1407h32v-1407h-32zM189 1v1407h31v-1407h-31zM346 1v1407h31v-1407h-31zM472 1v1407h62v-1407h-62zM629 1v1407h31v-1407h-31zM692 1v1407h31v-1407h-31zM755 1v1407h31v-1407h-31zM880 1v1407h63v-1407h-63zM1037 1v1407h63v-1407h-63z M1163 1v1407h63v-1407h-63zM1289 1v1407h63v-1407h-63zM1383 1v1407h63v-1407h-63zM1541 1v1407h94v-1407h-94zM1666 1v1407h32v-1407h-32zM1729 0v1408h63v-1408h-63z" /> +<glyph unicode="" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 864v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117zM192 1088q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5zM704 1408h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M10 184q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23 t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57 q38 -15 59 -43q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5zM575 1056 q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 160v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-224 q-13 0 -22.5 9.5t-9.5 22.5zM384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1408 576q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 128v896q0 106 75 181t181 75h224l51 136q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181zM512 576q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5zM672 576q0 119 84.5 203.5t203.5 84.5t203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -128l2 79q23 7 56 12.5t57 10.5t49.5 14.5t44.5 29t31 50.5l237 616l280 724h75h53q8 -14 11 -21l205 -480q33 -78 106 -257.5t114 -274.5q15 -34 58 -144.5t72 -168.5q20 -45 35 -57q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8 t-191 8q-76 0 -215 -7t-178 -8q0 43 4 78l131 28q1 0 12.5 2.5t15.5 3.5t14.5 4.5t15 6.5t11 8t9 11t2.5 14q0 16 -31 96.5t-72 177.5t-42 100l-450 2q-26 -58 -76.5 -195.5t-50.5 -162.5q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27 q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14zM555 527q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -128l2 94q15 4 85 16t106 27q7 12 12.5 27t8.5 33.5t5.5 32.5t3 37.5t0.5 34v35.5v30q0 982 -22 1025q-4 8 -22 14.5t-44.5 11t-49.5 7t-48.5 4.5t-30.5 3l-4 83q98 2 340 11.5t373 9.5q23 0 68.5 -0.5t67.5 -0.5q70 0 136.5 -13t128.5 -42t108 -71t74 -104.5 t28 -137.5q0 -52 -16.5 -95.5t-39 -72t-64.5 -57.5t-73 -45t-84 -40q154 -35 256.5 -134t102.5 -248q0 -100 -35 -179.5t-93.5 -130.5t-138 -85.5t-163.5 -48.5t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12zM533 1292q0 -50 4 -151t4 -152q0 -27 -0.5 -80 t-0.5 -79q0 -46 1 -69q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13zM538.5 165q0.5 -37 4.5 -83.5t12 -66.5q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25 t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 -126l17 85q6 2 81.5 21.5t111.5 37.5q28 35 41 101q1 7 62 289t114 543.5t52 296.5v25q-24 13 -54.5 18.5t-69.5 8t-58 5.5l19 103q33 -2 120 -6.5t149.5 -7t120.5 -2.5q48 0 98.5 2.5t121 7t98.5 6.5q-5 -39 -19 -89q-30 -10 -101.5 -28.5t-108.5 -33.5 q-8 -19 -14 -42.5t-9 -40t-7.5 -45.5t-6.5 -42q-27 -148 -87.5 -419.5t-77.5 -355.5q-2 -9 -13 -58t-20 -90t-16 -83.5t-6 -57.5l1 -18q17 -4 185 -31q-3 -44 -16 -99q-11 0 -32.5 -1.5t-32.5 -1.5q-29 0 -87 10t-86 10q-138 2 -206 2q-51 0 -143 -9t-121 -11z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q36 0 107.5 -0.5t107.5 -0.5h293q6 0 21 -0.5t20.5 0t16 3t17.5 9t15 17.5l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 48t-14.5 73.5t-7.5 35.5 q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5q-17 0 -66.5 0.5t-74.5 0.5t-64 -2t-71 -6q-9 -81 -8 -136q0 -94 2 -388t2 -455q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9 t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27q19 42 19 383q0 101 -3 303t-3 303v117q0 2 0.5 15.5t0.5 25t-1 25.5t-3 24t-5 14q-11 12 -162 12q-33 0 -93 -12t-80 -26q-19 -13 -34 -72.5t-31.5 -111t-42.5 -53.5q-42 26 -56 44zM1414 109.5q9 18.5 42 18.5h80v1024 h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5z" /> +<glyph unicode="" d="M0 1023v383l81 1l54 -27q12 -5 211 -5q44 0 132 2t132 2q70 0 246.5 1t304.5 0.5t247 -4.5q33 -1 56 31l42 1q4 0 14 -0.5t14 -0.5q2 -112 2 -336q0 -80 -5 -109q-39 -14 -68 -18q-25 44 -54 128q-3 9 -11 47.5t-15 73.5t-7 36q-10 13 -27 19q-5 2 -66 2q-30 0 -93 1 t-103 1t-94 -2t-96 -7q-9 -81 -8 -136l1 -152v52q0 -55 1 -154t1.5 -180t0.5 -153q0 -16 -2.5 -71.5t0 -91.5t12.5 -69q40 -21 124 -42.5t120 -37.5q5 -40 5 -50q0 -14 -3 -29l-34 -1q-76 -2 -218 8t-207 10q-50 0 -151 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29 t78 27q7 16 11.5 74t6 145.5t1.5 155t-0.5 153.5t-0.5 89q0 7 -2.5 21.5t-2.5 22.5q0 7 0.5 44t1 73t0 76.5t-3 67.5t-6.5 32q-11 12 -162 12q-41 0 -163 -13.5t-138 -24.5q-19 -12 -34 -71.5t-31.5 -111.5t-42.5 -54q-42 26 -56 44zM5 -64q0 28 26 49q4 3 36 30t59.5 49 t57.5 41.5t42 19.5q13 0 20.5 -10.5t10 -28.5t2.5 -33.5t-1.5 -33t-1.5 -19.5h1024q0 2 -1.5 19.5t-1.5 33t2.5 33.5t10 28.5t20.5 10.5q12 0 42 -19.5t57.5 -41.5t59.5 -49t36 -30q26 -21 26 -49t-26 -49q-4 -3 -36 -30t-59.5 -49t-57.5 -41.5t-42 -19.5q-13 0 -20.5 10.5 t-10 28.5t-2.5 33.5t1.5 33t1.5 19.5h-1024q0 -2 1.5 -19.5t1.5 -33t-2.5 -33.5t-10 -28.5t-20.5 -10.5q-12 0 -42 19.5t-57.5 41.5t-59.5 49t-36 30q-26 21 -26 49z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1536 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h896 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM128 832v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM384 448v128q0 26 19 45t45 19h1280 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM512 1216v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 64v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 448v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 832v128q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1216v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 416v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5zM0 800v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192 q-13 0 -22.5 9.5t-9.5 22.5zM384 32v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 416v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 800v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5zM384 1184v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5 t-9.5 22.5zM32 704q0 14 9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088 q-13 0 -22.5 9.5t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 32v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM0 416v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23t-9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5z M0 1184v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5zM640 416v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5 t-9.5 22.5zM640 800v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5q39 -17 39 -59v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5 t-84.5 203.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v192l320 320l160 -160l512 512l416 -416v-448h-1408zM256 960q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136z" /> +<glyph unicode="" d="M0 -128v416l832 832l416 -416l-832 -832h-416zM128 128h128v-128h107l91 91l-235 235l-91 -91v-107zM298 384q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17zM896 1184l166 165q36 38 90 38q53 0 91 -38l235 -234 q37 -39 37 -91q0 -53 -37 -90l-166 -166z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 896q0 212 150 362t362 150t362 -150t150 -362q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179zM256 896q0 -106 75 -181t181 -75t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73v1088q-148 0 -273 -73t-198 -198t-73 -273z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 512q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275q0 -212 -150 -362t-362 -150t-362 150t-150 362zM256 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29v-190 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM640 256v288l672 672l288 -288l-672 -672h-288zM736 448h96v-96h56l116 116l-152 152l-116 -116v-56zM944 688q16 -16 33 1l350 350q17 17 1 33t-33 -1l-350 -350q-17 -17 -1 -33zM1376 1280l92 92 q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68l-92 -92z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h255q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29v-259 q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM256 704q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45l-384 -384 q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5t-38.5 114t-17.5 122z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3 q20 -8 20 -29v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM257 768q0 33 24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110q24 -24 24 -57t-24 -57l-814 -814q-24 -24 -57 -24t-57 24l-430 430 q-24 24 -24 57z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256 q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 -64v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710q19 19 32 13t13 -32v-710q4 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45 t-45 -19h-128q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M122 640q0 26 19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19l710 710q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -96v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31l-1328 -738q-23 -13 -39.5 -3t-16.5 36z" /> +<glyph unicode="" d="M0 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM896 -64v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45z" /> +<glyph unicode="" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32v710 q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 -96v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710q-19 -19 -32 -13t-13 32z" /> +<glyph unicode="" horiz-adv-x="1538" d="M1 64v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM1 525q-6 13 13 32l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13z" /> +<glyph unicode="" horiz-adv-x="1280" d="M154 704q0 26 19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1280" d="M90 128q0 26 19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19 t19 45v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 576q0 -26 19 -45t45 -19h768q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19 t-19 -45v-128z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM387 414q0 -27 19 -46l90 -90q19 -19 46 -19q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19 l90 90q19 19 19 46q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 621q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45q0 28 -18 46l-91 90 q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM417 939q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26 t37.5 -59q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213zM640 160q0 -14 9 -23t23 -9 h192q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320 q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160zM640 1056q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160z" /> +<glyph unicode="" d="M0 576v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143 q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45zM339 512q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5h-109q-26 0 -45 19 t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM429 480q0 13 10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23l-137 -137l137 -137q10 -10 10 -23t-10 -23l-146 -146q-10 -10 -23 -10t-23 10l-137 137 l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM346 640q0 26 19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45z" /> +<glyph unicode="" d="M0 643q0 157 61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5t-61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61t-245 164t-163.5 246t-61 300zM224 643q0 -162 89 -299l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199 t-73 -274zM471 185q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5q0 161 -87 295z" /> +<glyph unicode="" d="M64 576q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5t32.5 -90.5v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90 z" /> +<glyph unicode="" d="M0 512v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M53 565q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651q37 -39 37 -91q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75 q-38 38 -38 90z" /> +<glyph unicode="" horiz-adv-x="1664" d="M53 704q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 416q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45t-19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123 q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22t-13.5 30t-10.5 24q-127 285 -127 451z" /> +<glyph unicode="" d="M0 -64v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45zM781 800q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448 q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" /> +<glyph unicode="" d="M13 32q0 13 10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23zM768 704v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10 t23 -10l114 -114q10 -10 10 -23t-10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M122.5 408.5q13.5 51.5 59.5 77.5l266 154l-266 154q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5 l-266 -154l266 -154q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM624 1126l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5l18 621q0 12 -10 18 q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18zM640 161q0 -13 10 -23t23 -10h192q13 0 22 9.5t9 23.5v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190z" /> +<glyph unicode="" d="M0 544v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23v-320q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68 t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23zM376 1120q0 -40 28 -68t68 -28h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68zM608 180q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5v56v468v192h-320v-192v-468v-56zM870 1024h194q40 0 68 28 t28 68t-28 68t-68 28q-43 0 -69 -31z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 121q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96 q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5zM384 448q0 -26 19 -45t45 -19q24 0 45 19 q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45t-19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -160q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64zM256 640q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100 t113.5 -122.5t72.5 -150.5t27.5 -184q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 576q0 34 20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69t-20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69zM128 576q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5q-152 236 -381 353 q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 576q0 38 20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5q16 -10 16 -27q0 -7 -1 -9q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87 q-143 65 -263.5 173t-208.5 245q-20 31 -20 69zM128 576q167 -258 427 -375l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353zM592 704q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34t-14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5zM896 0l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69t-20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95zM1056 286l280 502q8 -45 8 -84q0 -139 -79 -253.5t-209 -164.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M16 61l768 1408q17 31 47 49t65 18t65 -18t47 -49l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126zM752 992l17 -457q0 -10 10 -16.5t24 -6.5h185q14 0 23.5 6.5t10.5 16.5l18 459q0 12 -10 19q-13 11 -24 11h-220 q-11 0 -24 -11q-10 -7 -10 -21zM768 161q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 477q-1 13 9 25l96 97q9 9 23 9q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16 l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h288v288h-288v-288zM128 224 h288v320h-288v-320zM128 608h288v288h-288v-288zM384 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM480 -128h320v288h-320v-288zM480 224h320v320h-320v-320zM480 608h320v288h-320 v-288zM864 -128h320v288h-320v-288zM864 224h320v320h-320v-320zM864 608h320v288h-320v-288zM1152 1088q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288zM1248 -128h288v288h-288v-288z M1248 224h288v320h-288v-320zM1248 608h288v288h-288v-288z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 160v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23zM0 1056v192q0 14 9 23t23 9h224q250 0 410 -225q-60 -92 -137 -273q-22 45 -37 72.5 t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23zM743 353q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192 q-32 0 -85 -0.5t-81 -1t-73 1t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5 t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281z" /> +<glyph unicode="" d="M0 576v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5 t-98.5 362zM0 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45zM1024 960v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M90 250.5q0 26.5 19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M90 773.5q0 26.5 19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 704q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45z M640 1120q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20z " /> +<glyph unicode="" horiz-adv-x="1664" d="M0 1216q0 26 19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024 q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45zM384 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1280 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5t-0.5 12.5zM73 56q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43 q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43z" /> +<glyph unicode="" horiz-adv-x="768" d="M64 64q0 26 19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 26 19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216z M256 128v384h256v-384h-256zM640 128v896h256v-896h-256zM1024 128v640h256v-640h-256zM1408 128v1024h256v-1024h-256z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 286q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109 q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4q21 -63 74.5 -104 t121.5 -42q-116 -90 -261 -90q-26 0 -50 3z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-192v608h203l30 224h-233v143q0 54 28 83t96 29l132 1v207q-96 9 -180 9q-136 0 -218 -80.5t-82 -225.5v-166h-224v-224h224v-608h-544 q-119 0 -203.5 84.5t-84.5 203.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 0v1280q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5zM128 0h1536v128h-1536v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM256 1216h384v128h-384v-128zM512 574 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM640 574q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM736 576q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9 t9 23t-9 23t-23 9q-66 0 -113 -47t-47 -113z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 752q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41q0 -17 -49 -66t-66 -49 q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5zM192 768q0 -80 56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56 t56 136t-56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 549v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8 q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90 q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5zM384 640q0 -106 75 -181t181 -75 t181 75t75 181t-75 181t-181 75t-181 -75t-75 -181zM1152 58v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31 v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1152 1082v140q0 16 149 31q13 29 30 52 q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71 q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31zM1408 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90zM1408 1152q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5q0 52 -38 90t-90 38t-90 -38t-38 -90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM616 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5 t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" /> +<glyph unicode="" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5 t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85 t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640z" /> +<glyph unicode="" d="M0 512v640q0 53 37.5 90.5t90.5 37.5h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186 q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5zM128 1088q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 512h32q16 0 35.5 -9 t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5 t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640z" /> +<glyph unicode="" horiz-adv-x="896" d="M0 889q0 37 56 46l502 73l225 455q19 41 49 41v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 940q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138z M128 940q0 -168 187 -355l581 -560l580 559q188 188 188 356q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5 t-21.5 -143z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 288v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5q0 -4 1 -20t0.5 -26.5t-3 -23.5 t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5zM384 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM223 1030q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86z M237 122h231v694h-231v-694zM595 122h231v388q0 38 7 56q15 35 45 59.5t74 24.5q116 0 116 -157v-371h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 320q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19 t-19 45zM416 672q0 -14 9 -23t23 -9t23 9t9 23v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832 q-119 0 -203.5 84.5t-84.5 203.5zM685 576q0 13 10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23z" /> +<glyph unicode="" d="M0 448v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45t-19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45zM894.5 78.5q0.5 10.5 3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113 t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5q0 4 -1 20t-0.5 26.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 928v128q0 40 28 68t68 28h288v96q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91t97.5 -37q75 0 133.5 -45.5 t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143zM128 928q0 -78 94.5 -162t235.5 -113q-74 162 -74 371 h-256v-96zM1206 653q141 29 235.5 113t94.5 162v96h-256q0 -209 -74 -371z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204 q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52 t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5h-224q-119 0 -203.5 84.5t-84.5 203.5zM271 315q3 5 13 2 q10 -5 7 -12q-5 -7 -13 -2q-10 5 -7 12zM304 290q6 6 16 -3q9 -11 2 -16q-6 -7 -16 3q-9 11 -2 16zM335 233q-9 13 0 18q9 7 17 -6q9 -12 0 -19q-8 -6 -17 7zM370 206q8 9 20 -3q12 -11 4 -19q-8 -9 -20 3q-13 11 -4 19zM419 168q4 11 19 7q16 -5 13 -16q-4 -12 -19 -6 q-17 4 -13 15zM481 154q0 11 16 11q17 2 17 -11q0 -11 -16 -11q-17 -2 -17 11zM540 158q-2 12 14 15q16 2 18 -9q2 -10 -14 -14t-18 8z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -32v320q0 40 28 68t68 28h427q21 -56 70.5 -92t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68zM325 936q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69q-17 -40 -59 -40 h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40zM1152 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM1408 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" d="M0 433q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5q0 -165 -70 -327.5 t-196 -288t-281 -180.5q-124 -44 -326 -44q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5zM128 434q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5 q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24 q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 1069q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235 t235 -174q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5 t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832z" /> +<glyph unicode="" horiz-adv-x="1280" d="M0 7v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62zM128 38l423 406l89 85l89 -85l423 -406 v1242h-1024v-1242z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 905q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5 q6 -2 30 -11t33 -12.5t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5 t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M44 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5 q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145z" /> +<glyph unicode="" horiz-adv-x="1024" d="M95 631v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44 l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3 q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 96v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 32v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v608h-1664v-608zM128 1024h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600 q-13 0 -22.5 -9.5t-9.5 -22.5v-224zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 192q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 697v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5t259 -181.5q114 -113 181.5 -259t80.5 -306q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5 t-391.5 184.5q-25 2 -41.5 20t-16.5 43zM0 1201v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294q187 -186 294 -425.5t120 -501.5q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102 q-25 1 -42.5 19.5t-17.5 43.5z" /> +<glyph unicode="" d="M0 160v320q0 25 16 75l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113zM128 160q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-1216 q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM880 320q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1136 320q0 33 23.5 56.5t56.5 23.5 t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 672v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50 t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113zM768 633q377 -42 768 -341v954q-394 -302 -768 -343v-270z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" /> +<glyph unicode="" d="M2 435q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70l-53 -186l188 -48 q40 -10 52 -51q10 -42 -20 -70l-138 -135l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53 q-41 -12 -70 19q-31 29 -19 70l53 186l-188 48q-40 10 -52 51z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 128v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179q0 -105 -75.5 -181 t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5zM128 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM384 128h32q72 0 167 -32 t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139 q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106q-69 -57 -140 -57h-32v-640z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 769q0 103 76 179t180 76h374q-22 60 -22 128q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5v-640 q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181zM128 768q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119 q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5 t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576q-50 0 -89 -38.5t-39 -89.5zM1536 192q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" d="M0 640q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5t-90.5 -37.5h-640 q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5zM128 640q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140 v-32h640v32q0 72 32 167t64 193.5t32 179.5q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576q-20 0 -48.5 15t-55 33t-68 33t-84.5 15 q-67 0 -97.5 -44.5t-30.5 -115.5zM1152 -64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" d="M0 640q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317q0 -142 -77.5 -230t-217.5 -87 l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5zM128 640q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33t55 33t48.5 15v-576q0 -50 38.5 -89 t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112 q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5zM1152 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM251 640q0 -27 18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502 q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM256 576q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18 l362 362l91 91q18 18 18 45t-18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 641q0 -27 18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19 t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45t-18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM252 639q0 -27 18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45t-18 45l-91 91 q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM226 979q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18 q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13 q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5 t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13 q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25 t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5 t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4 q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5q15 10 -7 16q-17 5 -43 -12q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8 q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5 q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26 q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5 q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14 q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5 q-16 0 -22 -1q-146 -80 -235 -222zM877 26q0 -6 2 -16q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7 t-10 1.5t-11.5 -7q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M21 0q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90zM256 64q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45zM768 960q0 185 131.5 316.5t316.5 131.5q58 0 121.5 -16.5 t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25q0 -39 -23 -106q-47 -134 -164.5 -217.5t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 64v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 576v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM0 1088v256q0 26 19 45t45 19h1664 q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45zM640 640h1024v128h-1024v-128zM1024 128h640v128h-640v-128zM1280 1152h384v128h-384v-128z" /> +<glyph unicode="" horiz-adv-x="1408" d="M5 1241q17 39 59 39h1280q42 0 59 -39q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 160v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 736v384q0 66 47 113t113 47h352v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113v-384h-1792z M640 1280h512v128h-512v-128zM768 512v128h256v-128h-256z" /> +<glyph unicode="" d="M0 -64v448q0 42 40 59q39 17 69 -14l144 -144l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45 v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19l-144 144l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19 t-19 45z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 671q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5zM128 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM256 3q0 53 3.5 103.5 t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5 zM576 896q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5zM1280 1280q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181zM1327 640q81 117 81 256q0 29 -5 66q66 -23 133 -23 q59 0 119 21.5t97.5 42.5t43.5 21q124 0 124 -353q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128z" /> +<glyph unicode="" horiz-adv-x="1664" d="M16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l206 -207q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204t-85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88 q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204zM208 1088q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15t21.5 -21.5t18.5 -19q33 31 33 73 q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67zM911 383q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26l147 146q28 28 28 67q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5 q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 448q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M115.5 -64.5q-34.5 63.5 21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399l503 -793q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5zM476 384h712l-272 429l-20 31v37v399h-128v-399v-37 l-20 -31z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1 157q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148q4 -48 -10 -97q4 -1 12 -5 l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56l-507 -398l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207zM168 176q-25 -66 21 -108q39 -36 113 -36q100 0 192 59q81 51 106 117t-21 108q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117zM168 976q25 -66 106 -117q92 -59 192 -59q74 0 113 36q46 42 21 108t-106 117q-92 59 -192 59 q-74 0 -113 -36q-46 -42 -21 -108zM672 448l9 -8q2 -2 7 -6q4 -4 11 -12t11 -12l26 -26l160 96l96 -32l736 576l-128 64l-768 -431v-113zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 576q0 26 19 45t45 19t45 -19 t19 -45t-19 -45t-45 -19t-45 19t-19 45zM1018 391l582 -327l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 224v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68zM128 256h512v256q0 40 20 88t48 76l316 316v416h-384 v-416q0 -40 -28 -68t-68 -28h-416v-640zM213 1024h299v299zM768 -128h896v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640zM853 640h299v299z" /> +<glyph unicode="" horiz-adv-x="1408" d="M4 1023q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581 q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776 q-113 115 -113 271z" /> +<glyph unicode="" d="M0 -32v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 0h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20 t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280zM384 0h768v384h-768v-384zM640 928q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5z" /> +<glyph unicode="" d="M0 64v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 576v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM0 1088v128q0 26 19 45t45 19h1408 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 128q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 640q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM0 1152q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM512 32v192 q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z M512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M15 438q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105v-159h-362q-6 36 -6 54zM19 -190 l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66zM34 1400l136 127h106v-404h108v-99 h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54zM512 32v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 544v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5v-192 q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5zM512 1056v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 544v64q0 14 9 23t23 9h1728q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23zM384 972q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6l-14 2q-50 149 -103 205 q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743q-28 35 -51 80q-48 97 -48 188zM414 154q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22 q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156z" /> +<glyph unicode="" d="M0 -32v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-1472q-14 0 -23 -9t-9 -23zM0 1405q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5 t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2 q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195 q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39q-37 2 -45 4z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 160v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 544q0 -14 9 -23t23 -9h320 q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM128 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192zM640 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM640 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 160q0 -14 9 -23t23 -9h320q14 0 23 9t9 23 v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 544q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192zM1152 928q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192z" /> +<glyph unicode="" horiz-adv-x="1664" d="M27 160q0 27 18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45t-18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45zM128 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM320 1216l196 60l60 196l60 -196l196 -60l-196 -60 l-60 -196l-60 196zM768 1408l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98zM1083 1062l107 -107l293 293l-107 107zM1408 768l98 30l30 98l30 -98l98 -30l-98 -30l-30 -98l-30 98z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 192q0 26 19 45t45 19v320q0 8 -0.5 35t0 38t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45v-1024q0 -15 -4 -26.5t-13.5 -18.5t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5 q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM384 128q0 -52 38 -90t90 -38 t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90zM1280 128q0 -52 38 -90t90 -38t90 38t38 90t-38 90t-90 38t-90 -38t-38 -90z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63 q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5 q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5 q-104 0 -194.5 -28.5t-153 -76.5t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118 q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM276 309q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117 q0 49 -20 89.5t-49 66.5t-58 47.5t-49 44t-20 44.5t15.5 42.5t37.5 39.5t44 42t37.5 59.5t15.5 82.5q0 60 -22.5 99.5t-72.5 90.5h83l88 64h-265q-85 0 -161 -32t-127.5 -98t-51.5 -153q0 -93 64.5 -154.5t158.5 -61.5q22 0 43 3q-13 -29 -13 -54q0 -44 40 -94 q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95zM395 338q0 46 25 80t65.5 51.5t82 25t84.5 7.5q20 0 31 -2q2 -1 23 -16.5t26 -19t23 -18t24.5 -22t19 -22.5t17 -26t9 -26.5t4.5 -31.5q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78z M462 969q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5t-57.5 96.5t-17.5 106zM960 672h128v-160h64v160h128v64h-128v128h-64v-128h-128v-64z" /> +<glyph unicode="" horiz-adv-x="1664" d="M32 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q77 66 182.5 98t217.5 32h418l-138 -88h-131q74 -63 112 -133t38 -160q0 -72 -24.5 -129.5t-59 -93t-69.5 -65 t-59.5 -61.5t-24.5 -66q0 -36 32 -70.5t77.5 -68t90.5 -73.5t77 -104t32 -142q0 -90 -48 -173q-72 -122 -211 -179.5t-298 -57.5q-132 0 -246.5 41.5t-171.5 137.5q-37 60 -37 131zM218 228q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5q58 0 111.5 13t99 39t73 73 t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -48 2q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5zM324 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q38 0 78 16.5t66 43.5q53 57 53 159 q0 58 -17 125t-48.5 129.5t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160zM1084 731v108h212v217h105v-217h213v-108h-213v-219h-105v219h-212z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 64v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45zM128 384q106 0 181 -75t75 -181h1152q0 106 75 181t181 75v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512zM640 640q0 70 21 142 t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142t-21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142zM762 791l77 -80q42 37 55 57h2v-288h-128v-96h384v96h-128v448h-114z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 832q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 320q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="640" d="M64 640q0 26 19 45l448 448q19 19 45 19t45 -19t19 -45v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="640" d="M0 192v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 32v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113zM128 32q0 -13 9.5 -22.5t22.5 -9.5h608v1152h-640v-1120zM896 0h608q13 0 22.5 9.5t9.5 22.5v1120h-640v-1152z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45zM0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 448q0 26 19 45t45 19h896q26 0 45 -19t19 -45t-19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 832q0 26 19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 32v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113zM0 1098q0 78 41.5 130t118.5 52h1472 q65 0 112.5 -47t47.5 -113q0 -79 -49 -151t-122 -123q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5z" /> +<glyph unicode="" d="M0 1217q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122zM19 -80v991h330v-991h-330zM531 -80q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5v-568 h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329z" /> +<glyph unicode="" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M40 736q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18 q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5 q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5 t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 384q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29q-141 221 -141 483zM128 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M320 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM710 241q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91l101 382q6 26 -7.5 48.5t-38.5 29.5t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5 t-63 -98.5zM768 1024q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1216 832q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 384q0 -53 37.5 -90.5 t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 174 120 321.5t326 233t450 85.5t450 -85.5t326 -233t120 -321.5t-120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5 t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281zM128 640q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5t-381.5 -69.5 t-282 -187.5t-104.5 -255z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 768q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257t-94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25 t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224zM128 768q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52t-286 -52t-211.5 -141t-78.5 -191zM616 132 q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22 t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132z" /> +<glyph unicode="" horiz-adv-x="896" d="M1 551l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 -32v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 681q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17 q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5z M384 128q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180zM768 1310v98q0 26 19 45t45 19t45 -19t19 -45v-98q-42 2 -64 2t-64 -2z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 96v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88v-672q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68zM256 1312q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5v64 q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64zM768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1280 640h299l-299 299v-299z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 960q0 99 44.5 184.5t117 142t164 89t186.5 32.5t186.5 -32.5t164 -89t117 -142t44.5 -184.5q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47q0 -46 -31.5 -71t-77.5 -25 q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268zM128 960q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228 q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134zM480 1088q0 13 9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5 q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 256q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22zM0 800v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23 t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 608q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 448q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5z M512 672q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 131q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89 q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5 t81 -103t47.5 -132.5t24 -138t5.5 -131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190zM256 192q0 26 19 45t45 19t45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45zM320 1024q0 159 112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5 t-271.5 112.5t-112.5 271.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 768v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48 q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5 t-131.5 271.5v132q-164 20 -274 128t-110 252zM1152 832q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h64v-1280h-64q-92 0 -158 66t-66 158zM384 -128v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128v-1280h-1024zM640 1152h512v128h-512v-128zM1504 -128v1280h64q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-64z " /> +<glyph unicode="" horiz-adv-x="1664" d="M0 128q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38 t-38 90zM656 0q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM256 480v736q0 26 19 45t45 19h1152q159 0 271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158zM1408 704h64q80 0 136 56t56 136 t-56 136t-136 56h-64v-384z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 832v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128 q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111zM768 416v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM384 160v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64 q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 416v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM384 672v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1536h-1152v-1536zM256 160v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 928v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 1184v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 928v64q0 13 9.5 22.5t22.5 9.5h64 q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 1184v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -192v1280q0 26 19 45t45 19h320v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM128 -128h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224h384v1152h-256 v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152zM256 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM256 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64 q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM512 1056q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128 v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320zM768 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM768 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 160v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 416v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5zM1024 672v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5 v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M64 192q0 26 19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-1152q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128 q-26 0 -45 19t-19 45zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM384 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM896 800q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192 q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM1280 128q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 96v832q0 92 66 158t158 66h32v-1280h-32q-92 0 -158 66t-66 158zM352 -128v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160v-1280h-1088zM512 416q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23v192 q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192zM640 1152h512v128h-512v-128zM1536 -128v1280h32q92 0 158 -66t66 -158v-832q0 -92 -66 -158t-158 -66h-32z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 512v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93l1 -3q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5 t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8z" /> +<glyph unicode="" horiz-adv-x="1664" d="M64 1152l32 128h480l32 128h960l32 -192l-64 -32v-800l128 -192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320zM384 768q0 -53 37.5 -90.5t90.5 -37.5h128v384h-256v-256z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 192q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45 v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128z" /> +<glyph unicode="" horiz-adv-x="1024" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM429 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23 l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM397 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10 l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M77 224q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM77 608q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23 l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M77 672q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM77 1056q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10 l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="640" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="640" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M77 352q0 13 10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M77 800q0 13 10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 288v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113zM128 544q0 -13 9.5 -22.5 t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 96v96h160h1600h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68zM256 416v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088q-66 0 -113 47t-47 113zM384 416q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5 t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM864 112q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 160v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-832q-66 0 -113 47t-47 113zM128 288q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM512 128 q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="768" d="M0 128v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90zM96 288q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704zM288 1136 q0 -16 16 -16h160q16 0 16 16t-16 16h-160q-16 0 -16 -16zM304 128q0 -33 23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5t-23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z M896 192v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 832v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136zM896 832v384 q0 80 56 136t136 56h384q80 0 136 -56t56 -136v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136z" /> +<glyph unicode="" horiz-adv-x="1568" d="M0 640q0 66 47 113t113 47t113 -47t47 -113t-47 -113t-113 -47t-113 47t-47 113zM176 1088q0 73 51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5t-51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5zM208 192q0 60 42 102t102 42q59 0 101.5 -42t42.5 -102t-42.5 -102 t-101.5 -42q-60 0 -102 42t-42 102zM608 1280q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM672 0q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM1136 192q0 46 33 79t79 33t79 -33t33 -79 t-33 -79t-79 -33t-79 33t-33 79zM1168 1088q0 33 23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5t-23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5zM1344 640q0 40 28 68t68 28t68 -28t28 -68t-28 -68t-68 -28t-68 28t-28 68z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101 t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19l-512 512q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 496q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218q0 -87 -27 -168q136 -160 136 -398q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86t-170 -47.5t-171.5 -22t-167 -4.5 q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331zM224 320q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11 q-152 21 -195 21q-118 0 -187 -84t-69 -204zM384 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82zM1024 320q0 40 12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82t-12.5 -82t-43 -76t-72.5 -34t-72.5 34 t-43 76t-12.5 82z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158zM128 224q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64 q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 224v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158zM128 331l256 315q44 53 116 87.5 t140 34.5h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-853zM171 163q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40z " /> <glyph unicode="" horiz-adv-x="1792" /> <glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> -<glyph unicode="" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> -<glyph unicode="" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> -<glyph unicode="" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> -<glyph unicode="" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> -<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" /> -<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" /> -<glyph unicode="" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> -<glyph unicode="" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> -<glyph unicode="" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> -<glyph unicode="" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> -<glyph unicode="" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" /> -<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> -<glyph unicode="" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> -<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" /> -<glyph unicode="" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" /> -<glyph unicode="" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" /> -<glyph unicode="" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" /> -<glyph unicode="" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1024 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1024 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28 t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" /> -<glyph unicode="" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> -<glyph unicode="" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" /> -<glyph unicode="" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" /> -<glyph unicode="" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> -<glyph unicode="" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" /> -<glyph unicode="" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" /> -<glyph unicode="" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> -<glyph unicode="" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" /> -<glyph unicode="" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" /> -<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> -<glyph unicode="" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" /> -<glyph unicode="" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M390 1408h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170v217q91 30 155 84q64 55 103 132q39 78 54 196z " /> -<glyph unicode="" d="M1123 127v181q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> -<glyph unicode="" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> -<glyph unicode="" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> -<glyph unicode="" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> -<glyph unicode="" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> -<glyph unicode="" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1483 512l-587 -587q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128t53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41 l619 619l2 -3q53 -53 53 -128t-53 -128zM1406 1138l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15v0q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36t14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15z" /> -<glyph unicode="" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> -<glyph unicode="" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> -<glyph unicode="" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " /> -<glyph unicode="" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> -<glyph unicode="" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 461q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38 q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5q-37 -121 -138 -195t-228 -74t-228 74t-138 195zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM402 307q37 121 138 195t228 74t228 -74t138 -195q8 -25 -4 -48.5 t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM384 448q0 26 19 45t45 19h640q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45zM384 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5 t-90.5 -37.5t-90.5 37.5t-37.5 90.5zM896 896q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 512q0 212 150 362t362 150h896q212 0 362 -150t150 -362t-150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150t-150 362zM192 448q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23v128 q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128zM1152 384q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5zM1408 640q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 128v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5zM128 128h1664v896h-1664v-896zM256 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM256 528v96 q0 16 16 16h224q16 0 16 -16v-96q0 -16 -16 -16h-224q-16 0 -16 16zM256 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM512 272v96q0 16 16 16h864q16 0 16 -16v-96q0 -16 -16 -16h-864q-16 0 -16 16zM512 784v96q0 16 16 16h96q16 0 16 -16v-96 q0 -16 -16 -16h-96q-16 0 -16 16zM640 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM768 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM896 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z M1024 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1152 528v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1280 784v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16zM1408 528v96q0 16 16 16h112v240 q0 16 16 16h96q16 0 16 -16v-352q0 -16 -16 -16h-224q-16 0 -16 16zM1536 272v96q0 16 16 16h96q16 0 16 -16v-96q0 -16 -16 -16h-96q-16 0 -16 16z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 1280q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64zM320 320v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86 q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56zM448 426 q205 96 384 110v192q-181 -16 -384 -117v-185zM448 836q215 111 384 118v197q-172 -8 -384 -126v-189zM832 730h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15 t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2q-23 0 -49 -3v-222zM1280 828q148 -42 384 90v189q-169 -91 -306 -91q-45 0 -78 8v-196z" /> +<glyph unicode="" horiz-adv-x="1664" d="M13 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23zM640 32v64q0 14 9 23t23 9h960q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-960 q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M45 576q0 13 10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23zM712 -52l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5 l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5zM1293 160q0 13 10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45l397 -397v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45zM384 896q0 26 19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221 q169 -173 169 -509q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M2 900.5q9 27.5 54 34.5l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5z M832 310l59 -31l318 -168l-60 355l-12 66l49 47l257 250l-356 52l-66 10l-30 60l-159 322v-963z" /> +<glyph unicode="" horiz-adv-x="1408" d="M2 561q-5 22 4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 928v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864 q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23zM512 301l595 595h-595v-595zM557 256h595v595z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 64q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136 q0 -52 -26 -96.5t-70 -69.5q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136zM96 64q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM96 1216q0 -40 28 -68 t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68zM736 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 448q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23zM16 1088q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56l-239 -18l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68 l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204zM128 32q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23zM544 -96v320q0 14 9 23t23 9t23 -9t9 -23v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23zM633 364 l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56zM1056 1184v320q0 14 9 23t23 9t23 -9t9 -23v-320 q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1216 1120q0 13 9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23zM1280 960q0 14 9 23t23 9h320q14 0 23 -9t9 -23t-9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M96.5 986q-2.5 15 5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5t-10.5 37.5v45q0 83 65 156.5 t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25zM384 40v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28z" /> +<glyph unicode="" horiz-adv-x="640" d="M0 64v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45zM128 1152v192q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-192 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" /> +<glyph unicode="" horiz-adv-x="640" d="M98 1344q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45zM128 64v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45z" /> +<glyph unicode="" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1013 713q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80h126v-206h-514l-3 27q-4 28 -4 46z " /> +<glyph unicode="" d="M5 0v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258zM1015 -183q0 64 26 117t65 86.5 t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126v-206h-514l-4 27q-3 45 -3 46z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1.5 146.5q5.5 37.5 30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5zM128 128h768l336 384h-768z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 0v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5 q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124 q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89 q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45 t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5zM256 704v512q0 132 94 226t226 94t226 -94t94 -226v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226z" /> +<glyph unicode="" horiz-adv-x="1408" d="M13 64q0 13 10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23t-10 -23l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -221 -147.5 -384.5 t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23zM128 704v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113l-101 -101 q-42 103 -42 214zM384 704v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> +<glyph unicode="" horiz-adv-x="1280" d="M0 576v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150t-33.5 170.5zM640 79 q119 63 213 137q235 184 235 360v640h-448v-1137z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -128v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90zM128 -128h1408v1024h-1408v-1024z M384 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288zM1152 1088q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288z" /> +<glyph unicode="" horiz-adv-x="1408" d="M3.5 940q-8.5 25 3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96 q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37 zM384 1344q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M36 464l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85 q-3 -1 -9 -1q-14 0 -23 9l-64 64q-17 19 -5 39zM1248 1088q0 -40 28 -68t68 -28t68 28t28 68t-28 68t-68 28t-68 -28t-28 -68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 0l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM346 640q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l102 102q19 19 19 45t-19 45l-307 307l307 307 q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM506 288q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-454 454 q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 544q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19l102 102 q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM250 736q0 -26 19 -45l454 -454q19 -19 45 -19t45 19l454 454q19 19 19 45t-19 45l-102 102 q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 1408h1408l-128 -1438l-578 -162l-574 162zM262 1114l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674l16 175h-884z" /> +<glyph unicode="" horiz-adv-x="1792" d="M12 75l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208l59 297h1505l-266 -1333l-804 -267z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 0v352q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192 q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5 l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30zM832 1280q0 -26 19 -45t45 -19t45 19t19 45t-19 45t-45 19t-45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 96v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181v-320h736q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28 t-28 68z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5zM256 640q0 212 150 362t362 150t362 -150t150 -362t-150 -362t-362 -150t-362 150t-150 362zM384 640q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM512 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM1024 608v192q0 40 28 68t68 28h192 q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" /> +<glyph unicode="" horiz-adv-x="384" d="M0 96v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 608v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68zM0 1120v192q0 40 28 68t68 28h192q40 0 68 -28 t28 -68v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 256q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5t-37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5z M256 575q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10t9 24q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128zM256 959q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128 q13 0 23 10q11 9 9 23q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM512 320q0 -37 32 -56q16 -8 32 -8q17 0 32 9l544 320q32 18 32 55t-32 55l-544 320q-31 19 -64 1 q-32 -19 -32 -56v-640z" /> +<glyph unicode="" horiz-adv-x="1792" d="M54 448.5q0 53.5 37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136t-136 56t-136 -56l-125 126q-37 37 -37 90.5z M342 512q0 -26 19 -45l362 -362q18 -18 45 -18t45 18l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45zM452 512l572 572l316 -316l-572 -572z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 576q0 -26 19 -45t45 -19h896q26 0 45 19t19 45v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128 z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M3 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18z" /> +<glyph unicode="" horiz-adv-x="1024" d="M3 1261q9 19 29 19h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 640q0 -26 19 -45l358 -358q19 -19 45 -19t45 19l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19 t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 128h288l544 544l-288 288l-544 -544v-288zM352 320v56l52 52l152 -152l-52 -52h-56v96h-96zM494 494 q-14 13 3 30l291 291q17 17 30 3q14 -13 -3 -30l-291 -291q-17 -17 -30 -3zM864 1024l288 -288l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM282 320q0 -26 19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59 v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 448q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5t224 23.5v-160 q0 -42 40 -59q12 -5 24 -5q26 0 45 19l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 241v542l512 256v-542zM640 448l256 128l-256 128v-256z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 861q17 35 57 35h640q40 0 57 -35q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM391 419q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66q-17 -35 -57 -35h-640q-40 0 -57 35z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -14 9 -23t23 -9h960q14 0 23 9t9 23v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960z M512 320v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52t-27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 514v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5 t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5 l12 3l5 2q13 5 26 -2q12 -7 15 -21l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 32v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215 h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M52 171l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242 t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48 t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50t53 -63.5t31.5 -76.5t13 -94q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5 t-17.5 18q-17 21 -2 41z" /> +<glyph unicode="" horiz-adv-x="898" d="M0 605v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171 q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22z" /> +<glyph unicode="" horiz-adv-x="1027" d="M4 1360q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103 q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214z" /> +<glyph unicode="" horiz-adv-x="1280" d="M0 256v128q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315t-126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9 h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23zM487 747h320q106 0 171 62t65 162t-65 162t-171 62h-320v-448z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 672v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111 q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23z M373 896l32 -128h225l35 128h-292zM436 640l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5l81 299h-159zM822 768h139l-35 128h-70zM1118 896l34 -128h230l33 128h-297zM1187 640l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3l78 300h-162z" /> +<glyph unicode="" horiz-adv-x="1280" d="M56 0l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89 t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200zM522 182q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30t24.5 40t9.5 51q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1 t-47.5 -1v-338zM522 674q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM384 160q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 416q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM384 672q0 -14 9 -23t23 -9h704q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64zM1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472z" /> +<glyph unicode="" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 768v106h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106 h-287zM988 -166l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121v-233h-584v90zM1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18 t-7.5 -29z" /> +<glyph unicode="" horiz-adv-x="1664" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM899 -150h70l230 662h162l230 -662h70v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287 v106zM988 768v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248v119h121v-233h-584zM1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29 z" /> +<glyph unicode="" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM896 -32q0 14 9 23t23 9h256q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9 t-9 23v192zM896 288v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23zM896 800v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23zM896 1312v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23 v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23z" /> +<glyph unicode="" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 261q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 1351l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17 v16h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 261q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" /> +<glyph unicode="" d="M34 108q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35zM946 1285q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5q0 -62 -13 -121.5t-41 -114 t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5zM976 327l192 185h123v-654h165v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16 h-2l-7 -12q-8 -13 -26 -31l-62 -58zM1085 1285q0 -57 36.5 -95t104.5 -38q50 0 85 27t35 68q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 64v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45zM128 192q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45zM480 64v641q0 25 18 43.5t43 20.5q24 2 76 59 t101 121q68 87 101 120q18 18 31 48t17.5 48.5t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135 q0 -86 -55 -149q15 -44 15 -76q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 448q0 -26 19 -45t45 -19h288q26 0 45 19t19 45v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640zM128 960q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45zM480 447v641q0 26 19 44.5t45 19.5q35 1 158 44 q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76q55 -61 55 -149q-1 -78 -57.5 -135t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39 t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121t-76 59q-25 2 -43 20.5t-18 43.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM218 366q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73 q20 84 20 260q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5q-20 -87 -20 -260zM300 551v70h232v-70h-80v-423h-74v423h-78zM396 1313l24 -69t23 -69q35 -103 46 -158v-201h74v201l90 296h-75l-51 -195l-53 195 h-78zM542 205v290h66v-270q0 -24 1 -26q1 -15 15 -15q20 0 42 31v280h67v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54zM654 936q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38q-21 -29 -21 -87v-130zM721 923 v156q0 52 32 52t32 -52v-156q0 -51 -32 -51t-32 51zM790 128v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67zM857 200q16 -16 33 -16q29 0 29 49v157q0 50 -29 50q-17 0 -33 -16v-224zM907 893q0 -37 6 -55 q11 -27 43 -27q36 0 77 45v-40h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293zM1037 247v129q0 59 20 86q29 38 80 38t78 -38q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68v-9q0 -29 -2 -43q-3 -22 -15 -40 q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86zM1103 355h66v34q0 51 -33 51t-33 -51v-34z" /> +<glyph unicode="" d="M27 260q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99q-26 112 -26 350zM138 509h105v-569h100v569h107v94h-312 v-94zM266 1536h106l71 -263l68 263h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187zM463 43q0 -49 8 -73q12 -37 58 -37q48 0 102 61v-54h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391zM614 1028v175q0 80 28 117q38 51 105 51 q69 0 106 -51q28 -37 28 -117v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51q-28 38 -28 118zM704 1011q0 -70 43 -70t43 70v210q0 69 -43 69t-43 -69v-210zM798 -60h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89 v-663zM887 36v301q22 22 45 22q39 0 39 -67v-211q0 -67 -39 -67q-23 0 -45 22zM955 971v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75zM1130 100q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54 q2 9 2 58v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51q-28 -37 -28 -116v-173zM1219 245v46q0 68 45 68t45 -68v-46h-90z" /> +<glyph unicode="" horiz-adv-x="1408" d="M5 384q-10 17 0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45l164 -286q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17zM536 539q18 32 531 942q25 45 64 45h241q22 0 31 -15q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37 q-10 -15 -32 -15h-239q-42 0 -66 45z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM227 396q8 -13 24 -13h185q31 0 50 36l199 352q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29 l125 -216v-1l-196 -346q-9 -14 0 -28zM638 516q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1l409 723q8 16 0 28q-7 12 -24 12h-187q-30 0 -49 -35z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 96 1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150t-1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58 t-69.5 123q-14 65 -21.5 147.5t-8.5 136.5t-1 150zM640 320q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54t-30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 558l338 271l494 -305l-342 -285zM64 1099l490 319l342 -285l-494 -304zM407 166v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284l147 96v-108l-490 -293v-1l-1 1l-1 -1v1zM896 524l494 305l338 -271l-489 -319zM896 1133l343 285l489 -319l-338 -270z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -255v736h121v-618h928v618h120v-701l-1 -35v-1h-1132l-35 1h-1zM221 -17v151l707 1v-151zM227 243l14 150l704 -65l-13 -150zM270 563l39 146l683 -183l-39 -146zM395 928l77 130l609 -360l-77 -130zM707 1303l125 86l398 -585l-124 -85zM1136 1510l149 26l121 -697 l-149 -26z" /> +<glyph unicode="" d="M0 69v1142q0 81 58 139t139 58h1142q81 0 139 -58t58 -139v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139zM171 110q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62 q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648zM461 643q0 -124 90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5t-90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5zM1050 1003q0 -29 20 -49t49 -20h174q29 0 49 20t20 49v165q0 28 -20 48.5 t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM274 640q0 -88 62 -150t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150zM838 640q0 -88 62 -150 t150 -62t150 62t62 150t-62 150t-150 62t-150 -62t-62 -150z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM309 384h94l104 160h522l104 -160h94l-459 691zM567 608l201 306l201 -306h-402z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 1222q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34 t-6 39.5t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158zM173 285l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18t-76.5 27 t-73 43.5t-52 61.5q-25 96 -57 292zM243 1240q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5q-20 27 -56 44.5t-58 22t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43zM481 657q4 -91 77.5 -155t165.5 -56q91 8 152 84 t50 168q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5zM599 710q14 41 52 58q36 18 72.5 12t64 -35.5t27.5 -67.5q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM260 1060q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63 q24 13 39.5 23t31 29t19.5 40q48 267 80 473q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54zM385 384q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71q0 7 5.5 26.5t3 32 t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6zM436 1073q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5t-52.5 16t-54.5 32.5zM607 653q-2 49 25.5 93t72.5 64 q70 31 141.5 -10t81.5 -118q8 -66 -36 -121t-110 -61t-119 40t-56 113zM687.5 660.5q0.5 -52.5 43.5 -70.5q39 -23 81 4t36 72q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M78 779v217q91 30 155 84q64 55 103 132q39 78 54 196h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM413 744h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49v181 q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163z" /> +<glyph unicode="" horiz-adv-x="768" d="M3 237q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19t-5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35z" /> +<glyph unicode="" horiz-adv-x="768" d="M3 1043q-8 19 5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 637q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 544v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 634q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32 q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503zM683 1131q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 -27v557h682v-651zM0 614v565l682 94v-659h-682zM757 -131v661h907v-786zM757 614v669l907 125v-794h-907z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 337v430q0 42 30 72t73 30q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30t-73 30t-30 73zM241 886q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20l-71 -131q107 -55 171 -153.5t64 -215.5 h-925zM245 184v666h918v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78zM455 1092q0 -16 11 -27.5t27 -11.5t27.5 11.5t11.5 27.5t-11.5 27.5 t-27.5 11.5t-27 -11.5t-11 -27.5zM876 1092q0 -16 11.5 -27.5t27.5 -11.5t27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5zM1203 337v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73z" /> +<glyph unicode="" d="M11 -115q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48q3 -17 37 -26q20 -6 84.5 -18.5 t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195q-12 112 -16 310q-2 90 24 151.5 t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5 t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13 t16.5 -9.5q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5 q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5zM321 495q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54 t7 -70.5q46 24 7 92q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5 t60 -22.5q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18zM372 630q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12zM603 1190q2 -5 5 -6 q10 0 7 -15q-3 -20 8 -20q3 0 3 3q3 17 -2.5 30t-11.5 15q-9 2 -9 -7zM634 1110q0 12 19 15h10q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5zM721 1122q24 11 32 -2q3 -6 -3 -9q-4 -1 -11.5 6.5t-17.5 4.5zM835 1196l4 -2q14 -4 18 -31q0 -3 8 2l2 3q0 11 -5 19.5t-11 12.5 t-9 3q-14 -1 -7 -7zM851 1381.5q-1 -2.5 3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9zM981 1002q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20q-2 8 -6.5 11.5t-13 5 t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM112 640q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81t99.5 48l37 13 q4 1 13 3.5t13 4.5q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21zM126 775q302 0 606 80q-120 213 -244 378q-138 -65 -234 -186t-128 -272zM350 134q184 -150 418 -150q132 0 256 52q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5 t-103 -148zM609 1276q1 1 2 1q-1 0 -2 -1zM613 1277q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5l12.5 17.5q-185 164 -433 164q-76 0 -155 -19zM909 797q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5 t36.5 -6t25 -4.5l10 -2q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5zM1007 565q87 -239 128 -469q111 75 185 189.5t96 250.5q-210 60 -409 29z" /> +<glyph unicode="" d="M0 1024q0 159 112.5 271.5t271.5 112.5q130 0 234 -80q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225 t-55.5 273.5q0 73 16 150q-80 104 -80 234zM376 399q0 -92 122 -157.5t291 -65.5q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12 t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5 q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 640q0 75 53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41l619 619l2 -3q53 -53 53 -128t-53 -128l-587 -587 q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128zM302 660q0 21 14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36z" /> +<glyph unicode="" d="M0 -64v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM160 192q0 -14 9 -23t23 -9h480q14 0 23 9t9 23v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024zM832 576q0 -14 9 -23t23 -9h480q14 0 23 9t9 23 v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640z" /> +<glyph unicode="" horiz-adv-x="1280" d="M0 480q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192 q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43q-40 0 -68 28t-28 68zM416 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 416v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68z M288 1280q0 93 65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM399.5 766q8.5 -37 24.5 -59l349 -473l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5 t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85z" /> +<glyph unicode="" horiz-adv-x="1792" d="M44 363q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29q-4 -15 -20 -20 l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20zM320 640q0 -117 45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5 t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5z" /> +<glyph unicode="" d="M0 640q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384z" /> +<glyph unicode="" horiz-adv-x="1792" d="M64 1088v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-1536q-26 0 -45 19t-19 45zM128 -64v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45zM704 704q0 -26 19 -45t45 -19h256 q26 0 45 19t19 45t-19 45t-45 19h-256q-26 0 -45 -19t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M32 576q0 26 19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19t19 -45t-19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19 t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45z M512 1152q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5h-640z" /> +<glyph unicode="" horiz-adv-x="1920" d="M-1 1004q0 11 3 16l4 6q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24 q17 19 38 30q53 26 239 24q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5 t13 3t20 0.5l288 2q39 5 64 -2.5t31 -16.5l6 -10q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12 q-30 21 -70 64t-68.5 77.5t-61 58t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211 t-130.5 272q-6 16 -6 27z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 391q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5q0 -68 -37 -139.5 t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5zM181 320q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5zM413.5 230.5 q-40.5 92.5 6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5q-45 -102 -158 -150t-224 -12q-107 34 -147.5 126.5zM495 257.5q9 -34.5 43 -50.5t74.5 -2.5t62.5 47.5q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5zM705 399 q-17 -31 13 -45q14 -5 29 0.5t22 18.5q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5zM1165 1274q-6 28 9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158 q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5zM1224 1047q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5t54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37z" /> +<glyph unicode="" d="M0 638q0 187 83.5 349.5t229.5 269.5t325 137v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495zM398 -34q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211q-171 -94 -368 -94q-196 0 -367 94zM898 909v485q179 -30 325 -137t229.5 -269.5 t83.5 -349.5q0 -280 -181 -495q-204 99 -330.5 306.5t-126.5 459.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 -211q0 19 13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23 t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89 t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283 q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32z" /> +<glyph unicode="" horiz-adv-x="1280" d="M21 217v66h1238v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5zM21 354v255h1238v-255h-1238zM21 682v255h1238v-255h-1238zM21 1010v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5v-67h-1238z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 544v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23t-9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM384 640q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 160q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5v960q0 13 -9.5 22.5t-22.5 9.5h-960 q-13 0 -22.5 -9.5t-9.5 -22.5v-960zM448 640q0 33 27 52l448 320q17 12 37 12q26 0 45 -19t19 -45v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM224 640q0 -148 73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73t-273 -73 t-198 -198t-73 -273zM512 640q0 106 75 181t181 75t181 -75t75 -181t-75 -181t-181 -75t-181 75t-75 181z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 320q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5zM416 1348q-2 16 6 42 q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455l198 99l58 -114l-256 -128q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 806q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5 q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237q104 139 172.5 292.5t82.5 226.5q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143 q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7z" /> +<glyph unicode="" horiz-adv-x="1152" d="M0 608v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31 l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26z" /> +<glyph unicode="" horiz-adv-x="1408" d="M0 288v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5zM128 288q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47 t-47 -113v-832zM256 672v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="2176" d="M0 576q0 12 38.5 20.5t96.5 10.5q-7 25 -7 49q0 33 9.5 56.5t22.5 23.5h64v64h128q158 0 268 -64h1113q42 -7 106.5 -18t80.5 -14q89 -15 150 -40.5t83.5 -47.5t22.5 -40t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113q-110 -64 -268 -64h-128v64 h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5zM323 336h29q157 0 273 64h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96zM323 816l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5 t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64h-29zM1739 484l81 -30q68 48 68 122t-68 122l-81 -30q53 -36 53 -92t-53 -92z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 796q0 47 27.5 85t71.5 53l157 53l-53 159q-8 24 -8 47q0 60 42 102.5t102 42.5q47 0 85 -27t53 -72l54 -160l310 105l-54 160q-8 24 -8 47q0 59 42.5 102t101.5 43q47 0 85.5 -27.5t53.5 -71.5l53 -161l162 55q21 6 43 6q60 0 102.5 -39.5t42.5 -98.5q0 -45 -30 -81.5 t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8q62 0 103.5 -40.5t41.5 -101.5q0 -97 -93 -130l-172 -59l56 -167q7 -21 7 -47q0 -59 -42 -102t-101 -43q-47 0 -85.5 27t-53.5 72l-55 165l-310 -106l55 -164q8 -24 8 -47q0 -59 -42 -102t-102 -43q-47 0 -85 27t-53 72 l-55 163l-153 -53q-29 -9 -50 -9q-61 0 -101.5 40t-40.5 101q0 47 27.5 85t71.5 53l156 53l-105 313l-156 -54q-26 -8 -48 -8q-60 0 -101 40.5t-41 100.5zM620 811l105 -313l310 105l-105 315z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 352q0 -40 28 -68t68 -28h832q40 0 68 28t28 68v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99 q-98 -69 -164 -69t-164 69q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436zM256 928q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13 t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM41 640q0 -173 68 -331.5t182.5 -273t273 -182.5t331.5 -68t331.5 68t273 182.5t182.5 273t68 331.5 t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5zM127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM254 1062q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5 q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21t14.5 -24t14 -23q63 -107 63 -212q0 -19 -2.5 -38.5t-10 -49.5t-11.5 -44t-17.5 -59t-17.5 -58l-76 -256l-278 826q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-75 1 -202 10q-12 1 -20.5 -5t-11.5 -15 t-1.5 -18.5t9 -16.5t19.5 -8l80 -8l120 -328l-168 -504l-280 832q46 3 88 8q19 2 26 18.5t-2.5 31t-28.5 13.5l-205 -10q-7 0 -23 0.5t-26 0.5zM679 -97l230 670l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1282 -24l235 678q59 169 59 276q0 42 -6 79 q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 455q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360l272 133v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5zM1134 860v172q277 -33 481 -157l140 79l37 -390l-525 114l147 83 q-119 70 -280 99z" /> +<glyph unicode="" horiz-adv-x="2048" d="M0 -128q0 26 20.5 45t48.5 19h1782q28 0 48.5 -19t20.5 -45v-128h-1920v128zM0 1024v128l960 384l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128zM128 0v64q0 26 20.5 45t48.5 19h59v768h256v-768h128v768h256v-768h128v768h256 v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664z" /> +<glyph unicode="" horiz-adv-x="2304" d="M0 1024q0 23 22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31t-22 -31l-1120 -352q-4 -1 -10 -1t-10 1l-652 206q-43 -34 -71 -111.5t-34 -178.5q63 -36 63 -109q0 -69 -58 -107l58 -433q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433 q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31zM512 384l18 316l574 -181q22 -7 48 -7t48 7l574 181l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128z" /> +<glyph unicode="" d="M109 1536q58 -15 108 -15q43 0 111 15q63 -111 133.5 -229.5t167 -276.5t138.5 -227q37 61 109.5 177.5t117.5 190t105 176t107 189.5q54 -14 107 -14q56 0 114 14q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610l13 -707q-62 11 -105 11 q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287z" /> +<glyph unicode="" horiz-adv-x="1280" d="M111 182q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5t-15.5 73.5q0 40 21 85q-46 -4 -68 -4q-148 0 -249.5 96.5t-101.5 244.5q0 82 36 159t99 131q76 66 182 98t218 32h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5t-59.5 -93 t-69.5 -65t-59 -61.5t-24.5 -66q0 -36 32 -70.5t77 -68t90.5 -73.5t77.5 -104t32 -142q0 -91 -49 -173q-71 -122 -209.5 -179.5t-298.5 -57.5q-132 0 -246.5 41.5t-172.5 137.5q-36 59 -36 131zM297 228q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13 t99 39t73 73t27.5 109q0 25 -7 49t-14.5 42t-27 41.5t-29.5 35t-38.5 34.5t-36.5 29t-41.5 30t-36.5 26q-16 2 -49 2q-53 0 -104.5 -7t-107 -25t-97 -46t-68.5 -74.5t-27 -105.5zM403 1222q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5 q53 56 53 159q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160z" /> +<glyph unicode="" horiz-adv-x="1984" d="M0 722q0 94 66 160t160 66q83 0 148 -55q248 158 592 164l134 423q4 14 17.5 21.5t28.5 4.5l347 -82q22 50 68.5 81t102.5 31q77 0 131.5 -54.5t54.5 -131.5t-54.5 -132t-131.5 -55q-76 0 -130.5 54t-55.5 131l-315 74l-116 -366q327 -14 560 -166q64 58 151 58 q94 0 160 -66t66 -160q0 -62 -31 -114t-83 -82q5 -33 5 -61q0 -121 -68.5 -230.5t-197.5 -193.5q-125 -82 -285.5 -125.5t-335.5 -43.5q-176 0 -336.5 43.5t-284.5 125.5q-129 84 -197.5 193t-68.5 231q0 29 5 66q-48 31 -77 81.5t-29 109.5zM77 722q0 -67 51 -111 q49 131 180 235q-36 25 -82 25q-62 0 -105.5 -43.5t-43.5 -105.5zM178 465q0 -101 59.5 -194t171.5 -166q116 -75 265.5 -115.5t313.5 -40.5t313.5 40.5t265.5 115.5q112 73 171.5 166t59.5 194t-59.5 193.5t-171.5 165.5q-116 75 -265.5 115.5t-313.5 40.5t-313.5 -40.5 t-265.5 -115.5q-112 -73 -171.5 -165.5t-59.5 -193.5zM555 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM661 209.5q0 16.5 11 27.5t27 11t27 -11q77 -77 265 -77h2q188 0 265 77q11 11 27 11t27 -11t11 -27.5t-11 -27.5 q-99 -99 -319 -99h-2q-220 0 -319 99q-11 11 -11 27.5zM1153 572q0 57 41.5 98t97.5 41t96.5 -41t40.5 -98q0 -56 -40.5 -96t-96.5 -40q-57 0 -98 40t-41 96zM1555 1350q0 -45 32 -77t77 -32t77 32t32 77t-32 77t-77 32t-77 -32t-32 -77zM1672 843q131 -105 178 -238 q57 46 57 117q0 62 -43.5 105.5t-105.5 43.5q-49 0 -86 -28z" /> +<glyph unicode="" d="M0 193v894q0 133 94 227t226 94h896q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227zM155 709q0 -37 19.5 -67.5t52.5 -45.5q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54 q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48q-151 107 -375 115l83 265l206 -49q1 -50 36.5 -85t84.5 -35q50 0 86 35.5t36 85.5t-36 86t-86 36q-36 0 -66 -20.5t-45 -53.5l-227 54q-9 2 -17.5 -2.5t-11.5 -14.5l-95 -302q-224 -4 -381 -113q-36 43 -93 43 q-51 0 -87 -36.5t-36 -87.5zM493 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM560 375q0 11 8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18z M882 613q0 37 26 63t63 26t63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64zM1143 1120q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21q-29 0 -50 21t-21 50z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM320 502q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14 q19 0 32.5 -14t13.5 -33v-54l60 -28l90 27v62q0 79 -58 135t-138 56t-138 -55.5t-58 -134.5v-283q0 -20 -14 -33.5t-33 -13.5t-32.5 13.5t-13.5 33.5v120h-151v-122zM806 500q0 -80 58 -137t139 -57t138.5 57t57.5 139v122h-150v-126q0 -20 -13.5 -33.5t-33.5 -13.5 q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123z" /> +<glyph unicode="" horiz-adv-x="1920" d="M0 336v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58l-131 61v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5zM1062 332 v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275h328v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM64 640h704v-704h480q93 0 158.5 65.5t65.5 158.5v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480z " /> +<glyph unicode="" horiz-adv-x="2048" d="M0 271v697h328v286h204v-983h-532zM205 435h123v369h-123v-369zM614 271h205v697h-205v-697zM614 1050h205v204h-205v-204zM901 26v163h328v82h-328v697h533v-942h-533zM1106 435h123v369h-123v-369zM1516 26v163h327v82h-327v697h532v-942h-532zM1720 435h123v369h-123 v-369z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM293 388l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229t-88.5 229t-213.5 95q-74 0 -141 -36h-186v-840z M504 804v277q28 17 70 17q53 0 91 -45t38 -109t-38 -109.5t-91 -45.5q-43 0 -70 15zM636 -39l211 41v206q51 -19 117 -19q125 0 213 95t88 229t-88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101v-636zM847 377v277q28 17 70 17q53 0 91 -45.5t38 -109.5 t-38 -109t-91 -45q-43 0 -70 15z" /> +<glyph unicode="" horiz-adv-x="2038" d="M41 455q0 15 8.5 26.5t22.5 14.5l486 106q-8 14 -8 25t5.5 17.5t16 11.5t20 7t23 4.5t18.5 4.5q4 1 15.5 7.5t17.5 6.5q15 0 28 -16t20 -33q163 37 172 37q17 0 29.5 -11t12.5 -28q0 -15 -8.5 -26t-23.5 -14l-182 -40l-1 -16q-1 -26 81.5 -117.5t104.5 -91.5q47 0 119 80 t72 129q0 36 -23.5 53t-51 18.5t-51 11.5t-23.5 34q0 16 10 34l-68 19q43 44 43 117q0 26 -5 58q82 16 144 16q44 0 71.5 -1.5t48.5 -8.5t31 -13.5t20.5 -24.5t15.5 -33.5t17 -47.5t24 -60l50 25q-3 -40 -23 -60t-42.5 -21t-40 -6.5t-16.5 -20.5l1 -21q75 3 143.5 -20.5 t118 -58.5t101 -94.5t84 -108t75.5 -120.5q33 -56 78.5 -109t75.5 -80.5t99 -88.5q-48 -30 -108.5 -57.5t-138.5 -59t-114 -47.5q-44 37 -74 115t-43.5 164.5t-33 180.5t-42.5 168.5t-72.5 123t-122.5 48.5l-10 -2l-6 -4q4 -5 13 -14q6 -5 28 -23.5t25.5 -22t19 -18 t18 -20.5t11.5 -21t10.5 -27.5t4.5 -31t4 -40.5l1 -33q1 -26 -2.5 -57.5t-7.5 -52t-12.5 -58.5t-11.5 -53q-35 1 -101 -9.5t-98 -10.5q-39 0 -72 10q-2 16 -2 47q0 74 3 96q2 13 31.5 41.5t57 59t26.5 51.5q-24 2 -43 -24q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63 t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27zM764 676q10 1 32.5 7t34.5 6q19 0 35 -10l-96 -20zM822 568l48 12l109 -177l-73 -48zM859 884q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1 v-76l22 -1q247 95 371 190q28 21 50 39t42.5 37.5t33 31t29.5 34t24 31t24.5 37t23 38t27 47.5t29.5 53l7 9q-2 -53 -43 -139q-79 -165 -205 -264t-306 -142q-14 -3 -42 -7.5t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5 t-10 10.5l-8 8t-8.5 7.5t-8 5t-8.5 4.5q-7 3 -14.5 5t-20.5 2.5t-22 0.5h-32.5h-37.5q-126 0 -217 -43zM1061 45h31l10 -83l-41 -12v95zM1061 -79q39 26 131.5 47.5t146.5 21.5q9 0 22.5 -15.5t28 -42.5t26 -50t24 -51t14.5 -33q-121 -45 -244 -45q-61 0 -125 11zM1116 29 q21 2 60.5 8.5t72 10t60.5 3.5h14q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13t-54 -9.5t-53.5 -7.5t-32 -4.5zM1947 1528l1 3l2 4l-1 -5zM1950 1535v1v-1zM1950 1535l1 1z" /> +<glyph unicode="" d="M0 520q0 89 19.5 172.5t49 145.5t70.5 118.5t78.5 94t78.5 69.5t64.5 46.5t42.5 24.5q14 8 51 26.5t54.5 28.5t48 30t60.5 44q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5 t19.5 -177.5q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302zM333 256q-2 -112 74 -164q29 -20 62.5 -28.5t103.5 -8.5q57 0 132 32.5t134 71t120 70.5t93 31q26 -1 65 -31.5t71.5 -67t68 -67.5t55.5 -32q35 -3 58.5 14 t55.5 63q28 41 42.5 101t14.5 106q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14q-33 0 -97 -41.5t-129 -83.5t-101 -42q-27 -1 -63.5 19t-76 49t-83.5 58t-100 49t-111 19q-115 -1 -197 -78.5t-84 -178.5zM685.5 -76q-0.5 -10 7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5 q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29q-5 19 -24 5q-30 -22 -87 -39t-131 -17q-129 0 -193 49q-5 4 -13 4q-11 0 -26 -12q-7 -6 -7.5 -16zM852 31q9 -8 17.5 -4.5t31.5 23.5q3 2 10.5 8.5t10.5 8.5t10 7t11.5 7t12.5 5t15 4.5t16.5 2.5t20.5 1q27 0 44.5 -7.5 t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10q-29 -12 -78 -56q-26 -24 -12 -44z" /> +<glyph unicode="" d="M0 78q0 72 44.5 128t113.5 72q-22 86 1 173t88 152l12 12l151 -152l-11 -11q-37 -37 -37 -89t37 -90q37 -37 89 -37t89 37l30 30l151 152l161 160l151 -152l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5 t-60 145.5zM2 1202q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5t149.5 -87.5l12 -12l-152 -152l-12 12q-37 37 -89 37t-89 -37t-37 -89.5t37 -89.5l29 -29l152 -152l160 -160l-151 -152l-161 160l-151 152l-30 30q-68 67 -90 159.5t5 179.5 q-70 15 -115 71t-45 129zM446 803l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126t135.5 51q85 0 145 -60.5t60 -145.5q0 -77 -51 -135t-127 -69q26 -85 3 -176.5t-90 -158.5l-12 -12l-151 152l12 12q37 37 37 89t-37 89t-89 37t-89 -37l-30 -30l-152 -152 l-160 -160zM776 793l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5q76 -11 126.5 -68.5t50.5 -134.5q0 -85 -60 -145.5t-145 -60.5q-74 0 -131 47t-71 118q-86 -28 -179.5 -6t-161.5 90l-11 12l151 152l12 -12q37 -37 89 -37t89 37t37 89t-37 89l-30 30 l-152 152z" /> +<glyph unicode="" d="M0 -16v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5q20 0 20 -21v-418l147 -47v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3zM39 15l694 232v1032l-694 -233v-1031zM147 293q6 4 82 92 q21 24 85.5 115t78.5 118q17 30 51 98.5t36 77.5q-8 1 -110 -33q-8 -2 -27.5 -7.5t-34.5 -9.5t-17 -5q-2 -2 -2 -10.5t-1 -9.5q-5 -10 -31 -15q-23 -7 -47 0q-18 4 -28 21q-4 6 -5 23q6 2 24.5 5t29.5 6q58 16 105 32q100 35 102 35q10 2 43 19.5t44 21.5q9 3 21.5 8 t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5q-1 -3 -12.5 0.5t-31.5 11.5l-20 9q-44 20 -87 49q-7 5 -41 31.5t-38 28.5q-67 -103 -134 -181q-81 -95 -105 -110 q-4 -2 -19.5 -4t-18.5 0zM268 933l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41zM310 -116q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11q73 -37 159.5 -61.5t157.5 -24.5 q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5l-43 73l158 -13l-54 -160l-40 66q-130 -83 -276 -108q-58 -12 -91 -12h-84q-79 0 -199.5 39t-183.5 85q-8 7 -8 16zM777 1294l573 -184v380zM885 453l102 -31l45 110l211 -65l37 -135l102 -31l-181 657l-100 31z M1071 630l76 185l63 -227z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 -96v1088q0 66 47 113t113 47h128q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113zM512 -96v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-163q58 -34 93 -93t35 -128v-768q0 -106 -75 -181 t-181 -75h-864q-66 0 -113 47t-47 113zM640 896h896v256h-160q-40 0 -68 28t-28 68v160h-640v-512zM736 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM736 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9 h-128q-14 0 -23 -9t-9 -23v-128zM736 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 256q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM992 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 0q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23 v-128zM1248 256q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128zM1248 512q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128z" /> +<glyph unicode="" d="M0 -192v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45zM256 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM256 1184q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 96v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23zM512 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM512 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM512 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 928q0 -14 9 -23 t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM768 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 160q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64zM1024 416q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 672q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 928q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64zM1024 1184q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64z" /> +<glyph unicode="" horiz-adv-x="1280" d="M64 1056q0 40 28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68l-292 -292v-824q0 -46 -33 -79t-79 -33t-79 33t-33 79v384h-64v-384q0 -46 -33 -79t-79 -33t-79 33t-33 79v824l-292 292q-28 28 -28 68zM416 1152q0 93 65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5t-65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M0 724q0 80 42 139.5t119 59.5q76 0 141.5 -55.5t100.5 -134t35 -152.5q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152zM256 19q0 86 56 191.5t139.5 192.5t187.5 146t193 59q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45 t-64.5 -20t-76 -5.5q-68 0 -187.5 45t-182.5 45q-66 0 -192.5 -44.5t-200.5 -44.5q-183 0 -183 146zM333 1163q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151zM884 1064 q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5q-61 0 -105 39t-63 92.5t-19 113.5zM1226 581q0 74 35 152.5t100.5 134t141.5 55.5q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5 q-77 0 -119 59t-42 139z" /> +<glyph unicode="" horiz-adv-x="768" d="M64 1008q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5q0 -145 -57 -243.5t-152 -135.5l45 -821q2 -26 -16 -45t-44 -19h-192q-26 0 -44 19t-16 45l45 821q-95 37 -152 135.5t-57 243.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 256v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65zM134 1026l698 -254l698 254l-698 254zM896 -93l640 349v636l-640 -233v-752z" /> +<glyph unicode="" horiz-adv-x="2304" d="M0 96v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70v-400l434 -186q36 -16 57 -48t21 -70v-416q0 -36 -19 -67t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4 l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67zM172 531l404 -173l404 173l-404 173zM640 -96l384 192v314l-384 -164v-342zM647 1219l441 -189l441 189l-441 189zM1152 651l384 165v266l-384 -164v-267zM1196 531l404 -173l404 173l-404 173zM1664 -96 l384 192v314l-384 -164v-342z" /> +<glyph unicode="" horiz-adv-x="2048" d="M0 22v1260h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5 t45.5 113.5q0 144 -190 144h-260v-294zM1137 477q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658q0 -111 57.5 -171.5t166.5 -60.5q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347zM1337 1073h511v124 h-511v-124zM1388 576h408q-18 195 -200 195q-90 0 -146 -52.5t-62 -142.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 254h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5t-56.5 60.5t-79 29.5 t-97 8.5h-371v-787zM301 388v217h189q124 0 124 -113q0 -104 -128 -104h-185zM301 723v184h163q119 0 119 -90q0 -94 -106 -94h-176zM838 538q0 -135 79 -217t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20q-68 0 -104 38t-36 107h411q1 10 1 30 q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216zM964 911v77h319v-77h-319zM996 600q4 56 39 89t91 33q113 0 124 -122h-254z" /> +<glyph unicode="" horiz-adv-x="2048" d="M0 764q0 86 61 146.5t146 60.5q73 0 130 -46t73 -117l783 -315q49 29 106 29q14 0 21 -1l173 248q1 114 82 194.5t195 80.5q115 0 196.5 -81t81.5 -196t-81.5 -196.5t-196.5 -81.5l-265 -194q-8 -80 -67.5 -133.5t-138.5 -53.5q-73 0 -130 46t-73 117l-783 315 q-51 -30 -106 -30q-85 0 -146 61t-61 147zM55 764q0 -64 44.5 -108.5t107.5 -44.5q11 0 33 4l-64 26q-33 14 -52.5 44.5t-19.5 66.5q0 50 35.5 85.5t85.5 35.5q20 0 41 -8v1l76 -31q-20 37 -56.5 59t-78.5 22q-63 0 -107.5 -44.5t-44.5 -107.5zM1164 244q19 -37 55.5 -59 t79.5 -22q63 0 107.5 44.5t44.5 107.5t-44.5 108t-107.5 45q-13 0 -33 -4q2 -1 20 -8t21.5 -8.5t18.5 -8.5t19 -10t16 -11t15.5 -13.5t11 -14.5t10 -18t5 -21t2.5 -25q0 -50 -35.5 -85.5t-85.5 -35.5q-14 0 -31.5 4.5t-29 9t-31.5 13.5t-28 12zM1584 767q0 -77 54.5 -131.5 t131.5 -54.5t132 54.5t55 131.5t-55 131.5t-132 54.5q-76 0 -131 -54.5t-55 -131.5zM1623 767q0 62 43.5 105.5t104.5 43.5t105 -44t44 -105t-43.5 -104.5t-105.5 -43.5q-61 0 -104.5 43.5t-43.5 104.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM128 693q0 -53 38 -91t92 -38q36 0 66 18l489 -197q10 -44 45.5 -73t81.5 -29q50 0 86.5 34t41.5 83l167 122 q71 0 122 50.5t51 122.5t-51 123t-122 51q-72 0 -122.5 -50.5t-51.5 -121.5l-108 -155q-2 0 -6.5 0.5t-6.5 0.5q-35 0 -67 -19l-489 197q-10 44 -45.5 73t-80.5 29q-54 0 -92 -38t-38 -92zM162 693q0 40 28 68t68 28q27 0 49.5 -14t34.5 -37l-48 19q-29 11 -56.5 -2 t-38.5 -41q-12 -29 -0.5 -57t39.5 -40v-1l40 -16q-14 -2 -20 -2q-40 0 -68 27.5t-28 67.5zM855 369q5 -2 47 -19q29 -12 58 0.5t41 41.5q11 29 -1 57.5t-41 40.5l-40 16q14 2 21 2q39 0 67 -27.5t28 -67.5t-28 -67.5t-67 -27.5q-59 0 -85 51zM1118 695q0 48 34 82t83 34 q48 0 82 -34t34 -82t-34 -82t-82 -34q-49 0 -83 34t-34 82zM1142 696q0 -39 27.5 -66t65.5 -27t65.5 27t27.5 66q0 38 -27.5 65.5t-65.5 27.5t-65.5 -27.5t-27.5 -65.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M16 970l433 -17l180 -379l-147 92q-63 -72 -111.5 -144.5t-72.5 -125t-39.5 -94.5t-18.5 -63l-4 -21l-190 357q-17 26 -18 56t6 47l8 18q35 63 114 188zM270.5 158q-3.5 28 4 65t12 55t21.5 64t19 53q78 -12 509 -28l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5 q-11 27 -14.5 55zM294 1124l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5t36 -39.5t32 -35q-47 -63 -265 -435l-317 187zM782 1524l405 -1q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190l142 83l-220 -373l-419 20l151 86q-34 89 -75 166 t-75.5 123.5t-64.5 80t-47 46.5zM953 197l211 362l7 -173q170 -16 283 -5t170 33l56 22l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164zM1218 847l313 195l19 11l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22 t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436z" /> +<glyph unicode="" horiz-adv-x="1984" d="M0 160v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h704q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-928v-128q0 -80 -56 -136 t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23zM160 448q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 768h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 448q0 -66 47 -113t113 -47t113 47t47 113 t-47 113t-113 47t-113 -47t-47 -113z" /> +<glyph unicode="" horiz-adv-x="1984" d="M0 32v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h64q98 0 179 -63.5t104 -157.5l105 -419h28q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-128v-64q0 -80 -56 -136t-136 -56 t-136 56t-56 136v64h-928v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23zM160 320q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113zM516 640h952l-89 357q-2 8 -14 17.5t-21 9.5h-704q-9 0 -21 -9.5t-14 -17.5zM1472 320 q0 -66 47 -113t113 -47t113 47t47 113t-47 113t-113 47t-113 -47t-47 -113z" /> +<glyph unicode="" d="M32 64q0 26 19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384q19 19 45 19t45 -19l384 -384q19 -19 19 -45t-19 -45t-45 -19h-197l402 -403q19 -19 19 -45t-19 -45t-45 -19h-229l402 -403q19 -19 19 -45t-19 -45t-45 -19 h-462q1 -17 6 -87.5t5 -108.5q0 -25 -18 -42.5t-43 -17.5h-320q-25 0 -43 17.5t-18 42.5q0 38 5 108.5t6 87.5h-462q-26 0 -45 19t-19 45z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM237 886q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37q159 0 309.5 -34t253.5 -95q21 -12 40 -12 q29 0 50.5 20.5t21.5 51.5q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5zM289 637q0 -25 17.5 -42.5t42.5 -17.5q7 0 37 8q122 33 251 33q279 0 488 -124q24 -13 38 -13q25 0 42.5 17.5t17.5 42.5q0 40 -35 61 q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64zM321 406q0 -20 13.5 -34.5t35.5 -14.5q5 0 37 8q132 27 243 27q226 0 397 -103q19 -11 33 -11q19 0 33 13.5t14 34.5q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52z" /> +<glyph unicode="" d="M0 11v1258q0 58 40.5 98.5t98.5 40.5h1258q58 0 98.5 -40.5t40.5 -98.5v-1258q0 -58 -40.5 -98.5t-98.5 -40.5h-1258q-58 0 -98.5 40.5t-40.5 98.5zM71 11q0 -28 20 -48t48 -20h1258q28 0 48 20t20 48v1258q0 28 -20 48t-48 20h-1258q-28 0 -48 -20t-20 -48v-1258z M121 11v141l711 195l-212 439q4 1 12 2.5t12 1.5q170 32 303.5 21.5t221 -46t143.5 -94.5q27 -28 -25 -42q-64 -16 -256 -62l-97 198q-111 7 -240 -16l188 -387l533 145v-496q0 -7 -5.5 -12.5t-12.5 -5.5h-1258q-7 0 -12.5 5.5t-5.5 12.5zM121 709v560q0 7 5.5 12.5 t12.5 5.5h1258q7 0 12.5 -5.5t5.5 -12.5v-428q-85 30 -188 52q-294 64 -645 12l-18 -3l-65 134h-233l85 -190q-132 -51 -230 -137zM246 413q-24 203 166 305l129 -270l-255 -61q-14 -3 -26 4.5t-14 21.5z" /> +<glyph unicode="" horiz-adv-x="2304" d="M0 405l17 128q2 9 9 9t9 -9l20 -128l-20 -126q-2 -9 -9 -9t-9 9zM79 405l23 207q0 9 9 9q8 0 10 -9l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10zM169 405l21 245q2 12 12 12q11 0 11 -12l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11zM259 405l21 252q0 13 13 13 q12 0 14 -13l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13zM350 405l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5zM401 159zM442 405l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5l21 -380l-21 -246q0 -7 -5 -12.5 t-12 -5.5q-16 0 -18 18zM534 403l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19zM628 405l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5l18 -506l-18 -242q-2 -21 -22 -21q-19 0 -21 21zM723 405l14 -241 q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17zM784 164zM817 405l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18zM913 404l12 492q1 12 9 20t19 8t18.5 -8 t8.5 -20l14 -492l-14 -236q0 -11 -8 -19t-19 -8t-19 8t-9 19zM1010 405q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11q11 0 20 9q9 7 9 20l1 24l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6zM1079 169zM1103 404l12 636v3q2 15 12 24q9 7 20 7 q8 0 15 -5q14 -8 16 -26l14 -639l-14 -231q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114zM1204 174v899q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22z" /> +<glyph unicode="" d="M0 0v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 384v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 768 v170q119 -84 325 -127t443 -43t443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128zM0 1152v128q0 69 103 128t280 93.5t385 34.5t385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM257 60q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4 q52 85 107 197q68 136 104 262q-24 82 -30.5 159.5t6.5 127.5q11 40 42 40h21h1q23 0 35 -15q18 -21 9 -68q-2 -6 -4 -8q1 -3 1 -8v-30q-2 -123 -14 -192q55 -164 146 -238q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38 q-48 0 -115 20t-130 53q-221 -24 -392 -83q-153 -262 -242 -262q-15 0 -28 7l-24 12q-1 1 -6 5q-10 10 -6 36zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83z M714 842q1 7 7 44q0 3 7 43q1 4 4 8q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2q-15 -42 -2 -132zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1098 353q76 -28 124 -28q14 0 18 1q0 1 -2 3q-24 24 -140 24z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM233 661h70l164 -661h159l128 485q7 20 10 46q2 16 2 24 h4l3 -24q1 -3 3.5 -20t5.5 -26l128 -485h159l164 661h70v107h-300v-107h90l-99 -438q-5 -20 -7 -46l-2 -21h-4l-3 21q-1 5 -4 21t-5 25l-144 545h-114l-144 -545q-2 -9 -4.5 -24.5t-3.5 -21.5l-4 -21h-4l-2 21q-2 26 -7 46l-99 438h90v107h-300v-107zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM429 0h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4 h2q1 -4 5 -10q2 -4 4.5 -7.5t6 -8t6.5 -8.5l107 -161h-76v-106h291v106h-68l-192 273l195 282h67v107h-279v-107h74l-103 -159q-4 -7 -10 -16.5t-9 -13.5l-2 -3h-2q-1 4 -5 10q-6 11 -17 23l-106 159h76v107h-290v-107h68l189 -272l-194 -283h-68v-106zM1024 1024h376 q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM416 0h327v106h-93v167h137q76 0 118 15q67 23 106.5 87 t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92v-106zM650 386v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15h-119zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 0v192l192 192l128 -128l384 384l320 -320v-320 h-1024zM256 704q0 80 56 136t136 56t136 -56t56 -136t-56 -136t-136 -56t-136 56t-56 136zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536zM384 192q0 25 8 52q21 63 120 396 v128h128v-128h79q22 0 39 -13t23 -34l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5zM512 192q0 -26 37.5 -45t90.5 -19t90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45zM512 896h128v128h-128v-128zM512 1152h128v128h-128v-128 zM640 768h128v128h-128v-128zM640 1024h128v128h-128v-128zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 288v192q0 14 9 23t23 9h131l166 167q16 15 35 7 q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23zM762 206.5q1 -26.5 20 -44.5q20 -17 44 -17q27 0 47 20q87 93 87 219t-87 219q-18 19 -45 20t-46 -17t-20 -44.5t18 -46.5q52 -57 52 -131t-52 -131q-19 -20 -18 -46.5z M973.5 54.5q2.5 -26.5 23.5 -42.5q18 -15 40 -15q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM256 256v384q0 52 38 90t90 38h384q52 0 90 -38t38 -90 v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90zM960 403v90l265 266q9 9 23 9q4 0 12 -2q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M0 -160v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68zM128 -128h1280v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536zM254 429q-14 19 0 38l226 301q8 11 21 12.5t24 -6.5 l51 -38q11 -8 12.5 -21t-6.5 -24l-182 -243l182 -243q8 -11 6.5 -24t-12.5 -21l-51 -38q-11 -8 -24 -6.5t-21 12.5zM636 43l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5l-63 10q-13 2 -20.5 13t-5.5 24zM947.5 181 q-1.5 13 6.5 24l182 243l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5l226 -301q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21zM1024 1024h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376z" /> +<glyph unicode="" d="M39 1286h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406q-142 72 -223 220t-81 333q0 192 104 314.5t284 122.5q178 0 273 -105.5t95 -297.5q0 -159 -58 -286q-7 -1 -19.5 -3t-46 -2t-63 6t-62 25.5t-50.5 51.5q31 103 31 184q0 87 -29 132 t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14v-198q-101 -23 -198 -23q-65 -136 -165.5 -271t-181.5 -215.5t-128 -106.5q-80 -45 -162 3q-28 17 -60.5 43.5t-85 83.5t-102.5 128.5t-107.5 184t-105.5 244t-91.5 314.5t-70.5 390z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 367v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64v-546q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64zM154 511l193 129l-193 129v-258zM216 367l603 -402v359l-334 223zM216 913l269 -180l334 223v359zM624 640 l272 -182l272 182l-272 182zM973 -35l603 402l-269 180l-334 -223v-359zM973 956l334 -223l269 180l-603 402v-359zM1445 640l193 -129v258z" /> +<glyph unicode="" horiz-adv-x="2048" d="M0 407q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5 h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5zM468 498q0 -122 84 -193t208 -71q137 0 240 99q-16 20 -47.5 56.5t-43.5 50.5q-67 -65 -144 -65q-55 0 -93.5 33.5t-38.5 87.5q0 53 38.5 87t91.5 34q44 0 84.5 -21t73 -55t65 -75t69 -82t77 -75t97 -55t121.5 -21 q121 0 204.5 71.5t83.5 190.5q0 121 -84 192t-207 71q-143 0 -241 -97q14 -16 29.5 -34t34.5 -40t29 -34q66 64 142 64q52 0 92 -33t40 -84q0 -57 -37 -91.5t-94 -34.5q-43 0 -82.5 21t-72 55t-65.5 75t-69.5 82t-77.5 75t-96.5 55t-118.5 21q-122 0 -207 -70.5t-85 -189.5z " /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM128 640q0 -190 90 -361l194 194q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361zM512 640 q0 -159 112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5zM535 -38q171 -90 361 -90t361 90l-194 194q-82 -28 -167 -28t-167 28zM535 1318l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90t-361 -90z M1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 222 101 414.5t276.5 317t390.5 155.5v-260q-221 -45 -366.5 -221t-145.5 -406q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5 q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348z" /> +<glyph unicode="" horiz-adv-x="1792" d="M19 662q8 217 116 406t305 318h5q0 -1 -1 -3q-8 -8 -28 -33.5t-52 -76.5t-60 -110.5t-44.5 -135.5t-14 -150.5t39 -157.5t108.5 -154q50 -50 102 -69.5t90.5 -11.5t69.5 23.5t47 32.5l16 16q39 51 53 116.5t6.5 122.5t-21 107t-26.5 80l-14 29q-10 25 -30.5 49.5t-43 41 t-43.5 29.5t-35 19l-13 6l104 115q39 -17 78 -52t59 -61l19 -27q1 48 -18.5 103.5t-40.5 87.5l-20 31l161 183l160 -181q-33 -46 -52.5 -102.5t-22.5 -90.5l-4 -33q22 37 61.5 72.5t67.5 52.5l28 17l103 -115q-44 -14 -85 -50t-60 -65l-19 -29q-31 -56 -48 -133.5t-7 -170 t57 -156.5q33 -45 77.5 -60.5t85 -5.5t76 26.5t57.5 33.5l21 16q60 53 96.5 115t48.5 121.5t10 121.5t-18 118t-37 107.5t-45.5 93t-45 72t-34.5 47.5l-13 17q-14 13 -7 13l10 -3q40 -29 62.5 -46t62 -50t64 -58t58.5 -65t55.5 -77t45.5 -88t38 -103t23.5 -117t10.5 -136 q3 -259 -108 -465t-312 -321t-456 -115q-185 0 -351 74t-283.5 198t-184 293t-60.5 353z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 640q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348zM44 640q0 -173 67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331 t-67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331zM87 640q0 205 98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385zM206 217l58 34q29 -49 73 -99 l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13v-66q-208 6 -385 109.5t-283 275.5zM207 1063q106 172 282 275.5t385 109.5v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98zM415 805q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10 t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169l-233 -80q14 -42 14 -85t-14 -85l232 -80q-31 -92 -98 -169l-185 162q-57 -67 -147 -85l48 -241q-52 -10 -98 -10t-98 10l48 241q-90 18 -147 85l-185 -162q-67 77 -98 169l232 80q-14 42 -14 85t14 85zM918 -102 q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99l58 -34q-106 -172 -283 -275.5t-385 -109.5v66zM918 1382v66q209 -6 385 -109.5t282 -275.5l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13zM1516 428q36 103 36 212q0 112 -35 212l82 28 q-19 56 -49 112l57 33q98 -180 98 -385t-98 -385l-57 33q27 52 49 112z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 218q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5 t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85q0 -53 41 -77v-3q-113 -37 -113 -139zM382 225q0 64 98 64q102 0 102 -61q0 -66 -93 -66 q-107 0 -107 63zM395 693q0 90 77 90q36 0 55 -25.5t19 -63.5q0 -85 -74 -85q-77 0 -77 84zM755 1072q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392q0 -50 -3 -75z M966 771q36 3 37 3q3 0 11 -0.5t12 -0.5v-2h-2v-217q0 -37 2.5 -64t11.5 -56.5t24.5 -48.5t43.5 -31t66 -12q64 0 108 24v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117z" /> +<glyph unicode="" horiz-adv-x="1792" d="M68 7q0 165 182 225v4q-67 41 -67 126q0 109 63 137v4q-72 24 -119.5 108.5t-47.5 165.5q0 139 95 231.5t235 92.5q96 0 178 -47q98 0 218 47v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58q0 -31 22.5 -51.5t58 -32 t78.5 -22t86 -25.5t78.5 -37.5t58 -64t22.5 -98.5q0 -304 -363 -304q-69 0 -130 12.5t-116 41t-87.5 82t-32.5 127.5zM272 18q0 -101 172 -101q151 0 151 105q0 100 -165 100q-158 0 -158 -104zM293 775q0 -135 124 -135q119 0 119 137q0 61 -30 102t-89 41 q-124 0 -124 -145zM875 1389q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5t-39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5zM901 220q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134h-222zM1217 901v190h96v76q0 54 -6 89h227q-6 -41 -6 -165 h171v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33v-196q-71 -39 -174 -39q-62 0 -107 20t-70 50t-39.5 78t-18.5 92t-4 103v351h2v4q-7 0 -19 1t-18 1q-21 0 -59 -6z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM368 1135l323 -589v-435h134v436l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3 q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150z" /> +<glyph unicode="" horiz-adv-x="1280" d="M57 953q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5t-78 -292t-212.5 -212t-292.5 -78q-64 0 -131 14q-21 5 -32.5 23.5t-6.5 39.5q5 20 23 31.5t39 7.5q51 -13 108 -13q97 0 186 38t153 102t102 153t38 186t-38 186t-102 153 t-153 102t-186 38t-186 -38t-153 -102t-102 -153t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265zM113.5 38.5q10.5 121.5 29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5t136.5 -56.5 t56.5 -136.5t-57 -136.5t-136 -56.5q-60 0 -111 35q-62 -67 -115 -146q-247 -371 -202 -859q1 -22 -12.5 -38.5t-34.5 -18.5h-5q-20 0 -35 13.5t-17 33.5q-14 126 -3.5 247.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M18 264q0 275 252 466q-8 19 -8 52q0 20 11 49t24 45q-1 22 7.5 53t22.5 43q0 139 92.5 288.5t217.5 209.5q139 66 324 66q133 0 266 -55q49 -21 90 -48t71 -56t55 -68t42 -74t32.5 -84.5t25.5 -89.5t22 -98l1 -5q55 -83 55 -150q0 -14 -9 -40t-9 -38q0 -1 1.5 -3.5 t3.5 -5t2 -3.5q77 -114 120.5 -214.5t43.5 -208.5q0 -43 -19.5 -100t-55.5 -57q-9 0 -19.5 7.5t-19 17.5t-19 26t-16 26.5t-13.5 26t-9 17.5q-1 1 -3 1l-5 -4q-59 -154 -132 -223q20 -20 61.5 -38.5t69 -41.5t35.5 -65q-2 -4 -4 -16t-7 -18q-64 -97 -302 -97q-53 0 -110.5 9 t-98 20t-104.5 30q-15 5 -23 7q-14 4 -46 4.5t-40 1.5q-41 -45 -127.5 -65t-168.5 -20q-35 0 -69 1.5t-93 9t-101 20.5t-74.5 40t-32.5 64q0 40 10 59.5t41 48.5q11 2 40.5 13t49.5 12q4 0 14 2q2 2 2 4l-2 3q-48 11 -108 105.5t-73 156.5l-5 3q-4 0 -12 -20 q-18 -41 -54.5 -74.5t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100z" /> +<glyph unicode="" horiz-adv-x="2048" d="M0 858q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5q0 -78 23 -152q-35 -3 -68 -3q-26 0 -50 1.5t-55 6.5t-44.5 7t-54.5 10.5t-50 10.5l-253 -127l72 218q-290 203 -290 490z M380 1075q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5t-25 66t-66 25q-43 0 -76 -25.5t-33 -65.5zM816 404q0 143 81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109q-150 -37 -218 -37 q-169 0 -311 70.5t-223.5 191.5t-81.5 264zM888 1075q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5t-24.5 66t-65.5 25q-43 0 -76 -25.5t-33 -65.5zM1160 568q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5 t-22.5 -49.5zM1559 568q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 508q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-453 185l-242 -295q-18 -23 -49 -23q-13 0 -22 4q-19 7 -30.5 23.5t-11.5 36.5v349l864 1059l-1069 -925l-395 162q-37 14 -40 55z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 508q-3 39 32 59l1664 960q35 21 68 -2q33 -24 27 -64l-256 -1536q-5 -29 -32 -45q-14 -8 -31 -8q-11 0 -24 5l-527 215l-298 -327q-18 -21 -47 -21q-14 0 -23 4q-19 7 -30 23.5t-11 36.5v452l-472 193q-37 14 -40 55zM209 522l336 -137l863 639l-478 -797l492 -201 l221 1323z" /> +<glyph unicode="" d="M0 832v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298t-61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12 q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45zM512 480v64q0 14 9 23t23 9h224v352 q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23z" /> +<glyph unicode="" d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5zM128 640q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5 t-51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M62 1338q0 26 12 48t36 22q46 0 138.5 -3.5t138.5 -3.5q42 0 126.5 3.5t126.5 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17 -43.5t-38.5 -14.5t-49.5 -4t-43 -13q-35 -21 -35 -160l1 -320q0 -21 1 -32q13 -3 39 -3h699q25 0 38 3q1 11 1 32l1 320q0 139 -35 160 q-18 11 -58.5 12.5t-66 13t-25.5 49.5q0 26 12.5 48t37.5 22q44 0 132 -3.5t132 -3.5q43 0 129 3.5t129 3.5q25 0 37.5 -22t12.5 -48q0 -30 -17.5 -44t-40 -14.5t-51.5 -3t-44 -12.5q-35 -23 -35 -161l1 -943q0 -119 34 -140q16 -10 46 -13.5t53.5 -4.5t41.5 -15.5t18 -44.5 q0 -26 -12 -48t-36 -22q-44 0 -132.5 3.5t-133.5 3.5q-44 0 -132 -3.5t-132 -3.5q-24 0 -37 20.5t-13 45.5q0 31 17 46t39 17t51 7t45 15q33 21 33 140l-1 391q0 21 -1 31q-13 4 -50 4h-675q-38 0 -51 -4q-1 -10 -1 -31l-1 -371q0 -142 37 -164q16 -10 48 -13t57 -3.5 t45 -15t20 -45.5q0 -26 -12.5 -48t-36.5 -22q-47 0 -139.5 3.5t-138.5 3.5q-43 0 -128 -3.5t-127 -3.5q-23 0 -35.5 21t-12.5 45q0 30 15.5 45t36 17.5t47.5 7.5t42 15q33 23 33 143l-1 57v813q0 3 0.5 26t0 36.5t-1.5 38.5t-3.5 42t-6.5 36.5t-11 31.5t-16 18 q-15 10 -45 12t-53 2t-41 14t-18 45z" /> +<glyph unicode="" horiz-adv-x="1280" d="M24 926q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43v-73q0 -29 -18.5 -61t-42.5 -32q-50 0 -54 -1q-26 -6 -32 -31q-3 -11 -3 -64v-1152q0 -25 -18 -43t-43 -18h-108q-25 0 -43 18t-18 43v1218h-143v-1218q0 -25 -17.5 -43t-43.5 -18h-108 q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179q-64 117 -64 259z" /> +<glyph unicode="" d="M0 736v64q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM128 -96v672h256v-672q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM128 960v416q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-416h-256zM512 224v64q0 40 28 68 t68 28h320q40 0 68 -28t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM640 64h256v-160q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v160zM640 448v928q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-928h-256zM1024 992v64q0 40 28 68t68 28h320q40 0 68 -28 t28 -68v-64q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68zM1152 -96v928h256v-928q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23zM1152 1216v160q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-160h-256z" /> +<glyph unicode="" d="M0 640q0 133 93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5t-93.5 -226.5t-226.5 -93.5q-126 0 -218 86l-360 -180q2 -22 2 -34t-2 -34l360 -180q92 86 218 86q133 0 226.5 -93.5t93.5 -226.5 t-93.5 -226.5t-226.5 -93.5t-226.5 93.5t-93.5 226.5q0 12 2 34l-360 180q-92 -86 -218 -86q-133 0 -226.5 93.5t-93.5 226.5z" /> +<glyph unicode="" d="M0 160v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5zM256 640q0 -88 62.5 -150.5t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5 t150.5 62.5t62.5 150.5t-62.5 151t-150.5 63q-84 0 -145 -58l-241 120q2 16 2 23t-2 23l241 120q61 -58 145 -58q88 0 150.5 63t62.5 151t-62.5 150.5t-150.5 62.5t-151 -62.5t-63 -150.5q0 -7 2 -23l-241 -120q-62 57 -145 57q-88 0 -150.5 -62.5t-62.5 -150.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M0 448q0 143 55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68l243 244l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5 t-225 150t-150 225t-55.5 273.5zM170 615q10 -24 35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49t-34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49zM1376 1472q0 13 9 23q10 9 23 9t23 -9l90 -91q10 -9 10 -22.5t-10 -22.5 q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23zM1536 1408v96q0 14 9 23t23 9t23 -9t9 -23v-96q0 -14 -9 -23t-23 -9t-23 9t-9 23zM1605 1242.5q0 13.5 10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5z M1605 1381.5q0 13.5 10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5zM1632 1312q0 14 9 23t23 9h96q14 0 23 -9t9 -23t-9 -23t-23 -9h-96q-14 0 -23 9t-9 23z" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> <glyph unicode="" horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> +<glyph horiz-adv-x="1792" /> </font> </defs></svg>
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf Binary files differindex e89738de5e..5cd6cff6d6 100644..100755 --- a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff Binary files differindex 8c1748aab7..9eaecb3799 100644..100755 --- a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff diff --git a/WebContent/VAADIN/themes/base/notification/notification.scss b/WebContent/VAADIN/themes/base/notification/notification.scss index 0fc7801777..a91e26947d 100644 --- a/WebContent/VAADIN/themes/base/notification/notification.scss +++ b/WebContent/VAADIN/themes/base/notification/notification.scss @@ -33,8 +33,6 @@ } .#{$primaryStyleName}-system { background-color: red; - opacity: .7; - filter: alpha(opacity=70); } .#{$primaryStyleName}-system h1 { display: block; diff --git a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss index fbf78d40c4..85fbb3295f 100644 --- a/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss +++ b/WebContent/VAADIN/themes/chameleon/components/notification/notification.scss @@ -8,6 +8,9 @@ div.#{$primaryStyleName} { -webkit-box-shadow: 0 2px 5px rgba(0,0,0,.7); -moz-box-shadow: 0 2px 5px rgba(0,0,0,.7); box-shadow: 0 2px 5px rgba(0,0,0,.7); + //IE8 does not support rgba, using just rgb + background:rgb(255,255,255) url(../img/grad-light-top.png) repeat-x; + background:rgba(255,255,255,.90) url(../img/grad-light-top.png) repeat-x; } .#{$primaryStyleName} p { diff --git a/WebContent/VAADIN/themes/chameleon/components/tabsheet/tabsheet.scss b/WebContent/VAADIN/themes/chameleon/components/tabsheet/tabsheet.scss index dfa1c51c3a..d7f968fe43 100644 --- a/WebContent/VAADIN/themes/chameleon/components/tabsheet/tabsheet.scss +++ b/WebContent/VAADIN/themes/chameleon/components/tabsheet/tabsheet.scss @@ -89,6 +89,7 @@ .#{$primaryStyleName}-scrollerNext-disabled, .#{$primaryStyleName}-scrollerPrev-disabled:active, .#{$primaryStyleName}-scrollerNext-disabled:active { + padding-top: 12px; border: 1px solid #b3b3b3; border-width: 0; background: transparent url(../../img/tab-arrows.png) no-repeat 6px 50%; diff --git a/WebContent/VAADIN/themes/tests-responsive/styles.css b/WebContent/VAADIN/themes/tests-responsive/styles.css index db92a2a2fc..a06c920fe9 100644 --- a/WebContent/VAADIN/themes/tests-responsive/styles.css +++ b/WebContent/VAADIN/themes/tests-responsive/styles.css @@ -98,4 +98,19 @@ } .v-csslayout-width-and-height[height-range~="500px-"][width-range~="600px-"] { background: red; -}
\ No newline at end of file +} + +/* Styles for ResponsiveLayoutUpdate test */ +.layout-update .change-width { + white-space: normal; + background: #ddd; +} +.layout-update[width-range="0-599px"] .change-width { + width: 200px; + height: 200px; +} + +.layout-update[width-range="600px-"] .change-width { + width: 300px; + height: 300px; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_blueprint.scss b/WebContent/VAADIN/themes/tests-valo-blueprint/_variables.scss index 696da0b69e..696da0b69e 100644 --- a/WebContent/VAADIN/themes/tests-valo/_blueprint.scss +++ b/WebContent/VAADIN/themes/tests-valo-blueprint/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss b/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss new file mode 100644 index 0000000000..9433f4eba6 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-blueprint/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-blueprint { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_dark.scss b/WebContent/VAADIN/themes/tests-valo-dark/_variables.scss index 21bcd00ae9..ea40e1eb89 100644 --- a/WebContent/VAADIN/themes/tests-valo/_dark.scss +++ b/WebContent/VAADIN/themes/tests-valo-dark/_variables.scss @@ -9,10 +9,11 @@ $v-font-family: Roboto, sans-serif; $v-font-weight: 400; $v-font-weight--header: 400; $v-bevel: inset 0 1px 2px v-tint, inset 0 0 1px (v-tint 0.1); -$v-shadow: 0 0 0 3px darken($v-background-color, 3%), 0 1px 1px 3px lighten($v-background-color, 5%); +$v-shadow: 0 0 0 3px rgba(0,0,0,0.32), 0 1px 0 3px rgba(255,255,255,0.14); $v-textfield-bevel: inset 0 2px 2px v-shade; $v-textfield-shadow: $v-shadow; $v-unit-size: 40px; $v-overlay-shadow: 0 0 0 3px (v-shade 8), 0 5px 10px (v-shade 4); +$v-component-group-spacing: 6px; @import "../valo/valo"; diff --git a/WebContent/VAADIN/themes/tests-valo-dark/styles.scss b/WebContent/VAADIN/themes/tests-valo-dark/styles.scss new file mode 100644 index 0000000000..13f98ae418 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-dark/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-dark { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_facebook.scss b/WebContent/VAADIN/themes/tests-valo-facebook/_variables.scss index 5b83aae4ca..5b83aae4ca 100644 --- a/WebContent/VAADIN/themes/tests-valo/_facebook.scss +++ b/WebContent/VAADIN/themes/tests-valo-facebook/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss b/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss new file mode 100644 index 0000000000..7b784627b2 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-facebook/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-facebook { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_flat.scss b/WebContent/VAADIN/themes/tests-valo-flat/_variables.scss index 5d2b8abbb7..298e26ac36 100644 --- a/WebContent/VAADIN/themes/tests-valo/_flat.scss +++ b/WebContent/VAADIN/themes/tests-valo-flat/_variables.scss @@ -18,6 +18,7 @@ $v-selection-overlay-padding-horizontal: 0; $v-selection-overlay-padding-vertical: 6px; $v-selection-item-height: 30px; $v-selection-item-border-radius: 0; +$valo-menu-background-color: #eee; @import "../valo/valo"; diff --git a/WebContent/VAADIN/themes/tests-valo-flat/styles.scss b/WebContent/VAADIN/themes/tests-valo-flat/styles.scss new file mode 100644 index 0000000000..7b981de04a --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-flat/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-flat { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_flat-dark.scss b/WebContent/VAADIN/themes/tests-valo-flatdark/_variables.scss index f68f9c266d..fa785af8b8 100644 --- a/WebContent/VAADIN/themes/tests-valo/_flat-dark.scss +++ b/WebContent/VAADIN/themes/tests-valo-flatdark/_variables.scss @@ -1,7 +1,7 @@ $v-app-loading-text: "Dark & Flat Valo"; $v-background-color: #000; -$v-focus-color: orange; +$v-focus-color: #ffa500; $v-font-size: 15px; $v-font-weight: 600; $v-unit-size: 42px; diff --git a/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss b/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss new file mode 100644 index 0000000000..d0871fcba2 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-flatdark/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-flatdark { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_metro.scss b/WebContent/VAADIN/themes/tests-valo-metro/_variables.scss index f11cdb8b64..f11cdb8b64 100644 --- a/WebContent/VAADIN/themes/tests-valo/_metro.scss +++ b/WebContent/VAADIN/themes/tests-valo-metro/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo-metro/styles.scss b/WebContent/VAADIN/themes/tests-valo-metro/styles.scss new file mode 100644 index 0000000000..51b3427a12 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo-metro/styles.scss @@ -0,0 +1,6 @@ +@import "variables"; +@import "../tests-valo/valotest"; + +.tests-valo-metro { + @include valotest; +} diff --git a/WebContent/VAADIN/themes/tests-valo/_valotest.scss b/WebContent/VAADIN/themes/tests-valo/_valotest.scss new file mode 100644 index 0000000000..7c024b323e --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo/_valotest.scss @@ -0,0 +1,144 @@ +@mixin valotest { + @include valo; + + #themeSelect { + position: fixed; + z-index: 1000; + top: 0; + right: 0; + padding: 0 10px; + background-color: darken($v-app-background-color, 5%); + background-color: rgba(darken($v-app-background-color, 5%), .9); + color: valo-font-color($v-app-background-color); + border-radius: 0 0 0 $v-border-radius; + + &:before { + content: "Theme:"; + } + + select { + background: transparent; + color: inherit; + border: none; + display: inline-block; + } + } + + .v-ui { + @include width-range($max: 800px) { + #themeSelect { + top: $v-unit-size; + } + } + } + + $color1: hsl(220, 5%, 38%); + $color2: #5d73c0; + $color3: #3dbc1a; + $color4: #d2f4f3; + $color5: #fe902a; + $colors: $color1, $color2, $color3, $color4, $color5; + + .v-textfield-color1 { + @include valo-textfield-style($background-color: $color1); + } + + .v-textfield-color2 { + @include valo-textfield-style($background-color: $color3); + } + + .v-textfield-color3 { + @include valo-textfield-style($background-color: $color4); + } + + + .v-textarea-color1 { + @include valo-textarea-style($background-color: $color1); + } + + .v-textarea-color2 { + @include valo-textarea-style($background-color: $color3); + } + + .v-textarea-color3 { + @include valo-textarea-style($background-color: $color4); + } + + + .v-datefield-color1 { + @include valo-datefield-style($background-color: $color1); + } + + .v-datefield-color2 { + @include valo-datefield-style($background-color: $color3); + } + + .v-datefield-color3 { + @include valo-datefield-style($background-color: $color4); + } + + + .v-filterselect-color1 { + @include valo-combobox-style($background-color: $color1); + } + + .v-filterselect-color2 { + @include valo-combobox-style($background-color: $color3); + } + + .v-filterselect-color3 { + @include valo-combobox-style($background-color: $color4); + } + + + $copy: $v-selection-color; + $v-selection-color: white; + .v-checkbox-color1 { + @include valo-checkbox-style($background-color: $color1); + } + + .v-checkbox-color2 { + @include valo-checkbox-style($background-color: $color2); + } + $v-selection-color: $copy; + + + .v-slider-color1 { + @include valo-slider-handle-style($background-color: $color1); + } + + .v-slider-color2 { + @include valo-slider-track-style($background-color: $color3); + } + + .v-slider-color3 { + @include valo-slider-indicator-style($background-color: #dcdc1e); + } + + + .v-panel-caption-color1 { + @include valo-panel-caption-style($background-color: $color1); + } + + .v-panel-caption-color2 { + @include valo-panel-caption-style($background-color: $color3); + } + + .v-panel-caption-color3 { + @include valo-panel-caption-style($background-color: $color5); + } + + // Show splitpanel borders + .v-splitpanel-vertical, + .v-splitpanel-horizontal { + outline: 1px dotted rgba(gray, .2); + } + + .v-slider-ticks { + @include valo-slider-ticks($tick-count: 5); + } + + .v-accordion-item-color1 .v-accordion-item-caption { + @include valo-accordion-item-caption-style($background-color: $color2); + } +} diff --git a/WebContent/VAADIN/themes/tests-valo/_default.scss b/WebContent/VAADIN/themes/tests-valo/_variables.scss index c227156e2e..c227156e2e 100644 --- a/WebContent/VAADIN/themes/tests-valo/_default.scss +++ b/WebContent/VAADIN/themes/tests-valo/_variables.scss diff --git a/WebContent/VAADIN/themes/tests-valo/img/profile-pic-300px.jpg b/WebContent/VAADIN/themes/tests-valo/img/profile-pic-300px.jpg Binary files differnew file mode 100644 index 0000000000..8a98078243 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-valo/img/profile-pic-300px.jpg diff --git a/WebContent/VAADIN/themes/tests-valo/styles.scss b/WebContent/VAADIN/themes/tests-valo/styles.scss index 89fc5755f4..1ba0b29b04 100644 --- a/WebContent/VAADIN/themes/tests-valo/styles.scss +++ b/WebContent/VAADIN/themes/tests-valo/styles.scss @@ -1,127 +1,5 @@ -@import "default"; -// @import "flat"; -// @import "flat-dark"; -// @import "facebook"; -// @import "metro"; -// @import "dark"; -// @import "blueprint"; - - +@import "variables"; +@import "valotest"; .tests-valo { - @include valo; - - .valo-menu .v-checkbox { - margin: round($v-unit-size/2); - font-weight: 400; - } - - $color1: hsl(220, 5%, 38%); - $color2: #5d73c0; - $color3: #3dbc1a; - $color4: #d2f4f3; - $color5: #fe902a; - $colors: $color1, $color2, $color3, $color4, $color5; - - .v-textfield-color1 { - @include valo-textfield-style($background-color: $color1); - } - - .v-textfield-color2 { - @include valo-textfield-style($background-color: $color3); - } - - .v-textfield-color3 { - @include valo-textfield-style($background-color: $color4); - } - - - .v-textarea-color1 { - @include valo-textarea-style($background-color: $color1); - } - - .v-textarea-color2 { - @include valo-textarea-style($background-color: $color3); - } - - .v-textarea-color3 { - @include valo-textarea-style($background-color: $color4); - } - - - .v-datefield-color1 { - @include valo-datefield-style($background-color: $color1); - } - - .v-datefield-color2 { - @include valo-datefield-style($background-color: $color3); - } - - .v-datefield-color3 { - @include valo-datefield-style($background-color: $color4); - } - - - .v-filterselect-color1 { - @include valo-combobox-style($background-color: $color1); - } - - .v-filterselect-color2 { - @include valo-combobox-style($background-color: $color3); - } - - .v-filterselect-color3 { - @include valo-combobox-style($background-color: $color4); - } - - - $copy: $v-selection-color; - $v-selection-color: white; - .v-checkbox-color1 { - @include valo-checkbox-style($background-color: $color1); - } - - .v-checkbox-color2 { - @include valo-checkbox-style($background-color: $color2); - } - $v-selection-color: $copy; - - - .v-slider-color1 { - @include valo-slider-handle-style($background-color: $color1); - } - - .v-slider-color2 { - @include valo-slider-track-style($background-color: $color3); - } - - .v-slider-color3 { - @include valo-slider-indicator-style($background-color: #dcdc1e); - } - - - .v-panel-caption-color1 { - @include valo-panel-caption-style($background-color: $color1); - } - - .v-panel-caption-color2 { - @include valo-panel-caption-style($background-color: $color3); - } - - .v-panel-caption-color3 { - @include valo-panel-caption-style($background-color: $color5); - } - - // Show splitpanel borders - .v-splitpanel-vertical, - .v-splitpanel-horizontal { - outline: 1px dotted rgba(gray, .2); - } - - .v-slider-ticks { - @include valo-slider-ticks($tick-count: 5); - } - - .v-accordion-item-color1 .v-accordion-item-caption { - @include valo-accordion-item-caption-style($background-color: $color2); - } + @include valotest; } diff --git a/WebContent/VAADIN/themes/valo/_valo.scss b/WebContent/VAADIN/themes/valo/_valo.scss index b21cf733d1..f7d0534da1 100644 --- a/WebContent/VAADIN/themes/valo/_valo.scss +++ b/WebContent/VAADIN/themes/valo/_valo.scss @@ -44,10 +44,6 @@ @import "components/all"; -// Import common additional style names for components (optional) -@import "optional/common-stylenames"; - - // Include global styles directly, without a theme name prefix (this is done only once) @include valo-global; @@ -56,12 +52,4 @@ @mixin valo { @include valo-common; @include valo-components; - - @if v-is-included(notification) { - @include valo-notification; - } - - @if $valo-include-common-stylenames { - @include valo-common-stylenames; - } } diff --git a/WebContent/VAADIN/themes/valo/components/_accordion.scss b/WebContent/VAADIN/themes/valo/components/_accordion.scss index 350c704eb4..82a4396828 100644 --- a/WebContent/VAADIN/themes/valo/components/_accordion.scss +++ b/WebContent/VAADIN/themes/valo/components/_accordion.scss @@ -1,4 +1,4 @@ -@mixin valo-accordion ($primary-stylename: v-accordion) { +@mixin valo-accordion ($primary-stylename: v-accordion, $include-additional-styles: contains($v-included-additional-styles, accordion)) { .#{$primary-stylename} { @include valo-accordion-style; } @@ -14,6 +14,20 @@ .#{$primary-stylename}-item-content { @include valo-accordion-item-content-style; } + + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + border: none; + border-radius: 0; + @include box-shadow(none); + + > .#{$primary-stylename}-item { + border-radius: 0; + } + } + + } } diff --git a/WebContent/VAADIN/themes/valo/components/_all.scss b/WebContent/VAADIN/themes/valo/components/_all.scss index f20e8326bf..b41a2f3308 100644 --- a/WebContent/VAADIN/themes/valo/components/_all.scss +++ b/WebContent/VAADIN/themes/valo/components/_all.scss @@ -20,6 +20,7 @@ @import "menubar"; @import "nativebutton"; @import "nativeselect"; +@import "notification"; @import "optiongroup"; @import "orderedlayout"; @import "panel"; @@ -38,6 +39,7 @@ @import "upload"; @import "widget"; @import "window"; +@import "valo-menu"; @mixin valo-components { @@ -207,4 +209,12 @@ @include valo-upload; } + @if v-is-included(notification) { + @include valo-notification; + } + + @if v-is-included(valo-menu) { + @include valo-menu; + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_button.scss b/WebContent/VAADIN/themes/valo/components/_button.scss index cea1c9fbc8..ec74f70eaf 100644 --- a/WebContent/VAADIN/themes/valo/components/_button.scss +++ b/WebContent/VAADIN/themes/valo/components/_button.scss @@ -1,8 +1,83 @@ -@mixin valo-button ($primary-stylename: v-button) { +@mixin valo-button ($primary-stylename: v-button, $include-additional-styles: contains($v-included-additional-styles, button)) { .#{$primary-stylename} { @include valo-button-static-style; @include valo-button-style; } + + + @if $include-additional-styles { + .#{$primary-stylename}-primary { + @include valo-button-style($background-color: $v-selection-color); + $padding-width: round($v-unit-size/2); + padding: 0 $padding-width; + font-weight: bold; + $min-width: round($v-unit-size * 2.2); + min-width: $min-width; + + // IE8 + border-box + min-width == fail + .v-ie8 & { + min-width: $min-width - ($padding-width * 2); + } + } + + .#{$primary-stylename}-friendly { + @include valo-button-style($background-color: $v-friendly-color); + } + + .#{$primary-stylename}-danger { + @include valo-button-style($background-color: $v-error-indicator-color); + } + + .#{$primary-stylename}-borderless { + @include valo-button-borderless-style; + } + + .#{$primary-stylename}-borderless-colored { + @include valo-button-borderless-style($font-color: $v-selection-color); + } + + .#{$primary-stylename}-quiet { + @include valo-button-quiet-style; + } + + .#{$primary-stylename}-link { + @include valo-button-borderless-style; + @include valo-link-style; + } + + .#{$primary-stylename}-small { + @include valo-button-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $background-color: null, $font-size: $v-font-size--small, $font-weight: null); + } + + .#{$primary-stylename}-large { + @include valo-button-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $background-color: null, $font-size: $v-font-size--large, $font-weight: null); + } + + .#{$primary-stylename}-icon-align-right { + @include valo-button-icon-align-right-style; + } + + .#{$primary-stylename}-icon-align-top { + @include valo-button-icon-align-top-style; + } + + .#{$primary-stylename}-icon-only { + width: $v-unit-size; + padding: 0; + + &.#{$primary-stylename}-small { + width: $v-unit-size--small; + } + + &.#{$primary-stylename}-large { + width: $v-unit-size--large; + } + + .#{$primary-stylename}-caption { + display: none; + } + } + } } @@ -241,6 +316,11 @@ .#{$primary-stylename}-wrap { visibility: visible; } + + .#{$primary-stylename}-caption { + // For IE8 + display: inline-block; + } } diff --git a/WebContent/VAADIN/themes/valo/components/_checkbox.scss b/WebContent/VAADIN/themes/valo/components/_checkbox.scss index 0ee703c372..e74781fc46 100644 --- a/WebContent/VAADIN/themes/valo/components/_checkbox.scss +++ b/WebContent/VAADIN/themes/valo/components/_checkbox.scss @@ -1,9 +1,22 @@ -@mixin valo-checkbox ($primary-stylename: v-checkbox) { +@mixin valo-checkbox ($primary-stylename: v-checkbox, $include-additional-styles: contains($v-included-additional-styles, checkbox)) { .#{$primary-stylename} { @include valo-checkbox-style; } + + @if $include-additional-styles { + .#{$primary-stylename}-small { + @include valo-checkbox-style($unit-size: $v-unit-size--small); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-checkbox-style($unit-size: $v-unit-size--large); + font-size: $v-font-size--large; + } + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss index 4509c23f15..4460aafb21 100644 --- a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss +++ b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss @@ -203,6 +203,23 @@ + .v-button-caption:not(:empty) { margin-left: round($v-unit-size/2); } + + .v-ie8 & { + position: relative; + top: auto; + right: auto; + bottom: auto; + left: auto; + width: $v-font-size; + height: $v-font-size; + display: inline-block; + vertical-align: middle; + margin: 0 round($v-font-size / -2); + + + .v-button-caption { + margin-left: round($v-unit-size/2); + } + } } } diff --git a/WebContent/VAADIN/themes/valo/components/_combobox.scss b/WebContent/VAADIN/themes/valo/components/_combobox.scss index 51ec65e55f..4e5cd5bbac 100644 --- a/WebContent/VAADIN/themes/valo/components/_combobox.scss +++ b/WebContent/VAADIN/themes/valo/components/_combobox.scss @@ -1,4 +1,4 @@ -@mixin valo-combobox ($primary-stylename: v-filterselect) { +@mixin valo-combobox ($primary-stylename: v-filterselect, $include-additional-styles: contains($v-included-additional-styles, combobox)) { .#{$primary-stylename} { position: relative; @@ -59,6 +59,35 @@ } } + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + .#{$primary-stylename}-input { + @include valo-textfield-borderless-style; + } + .#{$primary-stylename}-button { + border: none; + } + } + + .#{$primary-stylename}-align-right input { + text-align: right; + } + + .#{$primary-stylename}-align-center input { + text-align: center; + } + + .#{$primary-stylename}-small { + @include valo-combobox-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $gradient: null, $border: null, $border-radius: null, $background-color: null, $states: normal); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-combobox-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $gradient: null, $border: null, $border-radius: null, $background-color: null, $states: normal); + font-size: $v-font-size--large; + } + } } @@ -81,7 +110,8 @@ $bevel: $v-textfield-bevel, $shadow: $v-textfield-shadow, - $primary-stylename: v-filterselect + $primary-stylename: v-filterselect, + $states: normal focus disabled ) { height: $unit-size; @@ -98,7 +128,8 @@ $background-color: $background-color, $font-color: $font-color, $font-size: $font-size, - $font-weight: $font-weight); + $font-weight: $font-weight, + $states: $states); } .v-icon + .#{$primary-stylename}-input { @@ -172,7 +203,9 @@ $gradient: none, $bevel: $v-bevel, - $shadow: $v-shadow + $shadow: $v-shadow, + + $states: normal focus disabled ) { @include box-sizing(border-box); @include valo-textfield-style($unit-size: $unit-size, @@ -185,7 +218,8 @@ $border-radius: $border-radius, $gradient: $gradient, $bevel: $bevel, - $shadow: $shadow); + $shadow: $shadow, + $states: $states); width: 100% !important; // Need to override calculated inline style which is sometimes added height: 100%; padding-right: round($unit-size * 1.2); diff --git a/WebContent/VAADIN/themes/valo/components/_csslayout.scss b/WebContent/VAADIN/themes/valo/components/_csslayout.scss index 3cefbb0a4b..95bdcc5a3a 100644 --- a/WebContent/VAADIN/themes/valo/components/_csslayout.scss +++ b/WebContent/VAADIN/themes/valo/components/_csslayout.scss @@ -1,63 +1,77 @@ -@mixin valo-csslayout ($primary-stylename: v-csslayout){ +$v-component-group-spacing: null !default; -} +@mixin valo-csslayout ($primary-stylename: v-csslayout, $include-additional-styles: contains($v-included-additional-styles, csslayout)){ + @if $include-additional-styles { + .#{$primary-stylename}-well { + @include valo-panel-well-style; + @include valo-panel-adjust-content-margins; + } -@mixin valo-component-group ($primary-stylename: v-csslayout) { - .#{$primary-stylename}-v-component-group { - white-space: nowrap; - position: relative; + .#{$primary-stylename}-card { + @include valo-panel-style; + @include valo-panel-adjust-content-margins; + } - @if $v-border-radius > 0 { - .v-widget ~ .v-widget:not(:last-child) { - border-radius: 0; - } + .#{$primary-stylename}-v-component-group { + @include valo-component-group($primary-stylename); + } + } +} - .v-widget:last-child { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - .v-widget:first-child, - .v-caption:first-child + .v-widget { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } +@mixin valo-component-group { + white-space: nowrap; + position: relative; - .v-widget ~ .v-widget.first.first { - border-radius: $v-border-radius 0 0 $v-border-radius; - } + @if $v-border-radius > 0 { + .v-widget ~ .v-widget:not(:last-child) { + border-radius: 0; + } - .v-widget ~ .v-widget.last.last { - border-radius: 0 $v-border-radius $v-border-radius 0; - } + .v-widget:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; } - // Assume most components have borders. - // This is just a best-guess, will need fine-tuning if border-widths vary from widget-to-widget - .v-widget { - vertical-align: middle; + .v-widget:first-child, + .v-caption:first-child + .v-widget { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } - $v-border-width: first-number($v-border); + .v-widget ~ .v-widget.first.first { + border-radius: $v-border-radius 0 0 $v-border-radius; + } + + .v-widget ~ .v-widget.last.last { + border-radius: 0 $v-border-radius $v-border-radius 0; + } + } - @if $v-border-width > 0 { - margin-left: -$v-border-width; - } @else { - margin-left: 1px; - } + // Assume most components have borders. + // This is just a best-guess, will need fine-tuning if border-widths vary from widget-to-widget + .v-widget { + vertical-align: middle; - &:first-child { - margin-left: 0; - } + $v-border-width: first-number($v-border); - // Focused component should be on top - &:focus, - &[class*="focus"], - [class*="focus"] { - position: relative; - z-index: 5; - } + @if $v-border-width > 0 { + margin-left: $v-component-group-spacing or -$v-border-width; + } @else { + margin-left: $v-component-group-spacing or 1px; } + &:first-child { + margin-left: 0; + } + + // Focused component should be on top + &:focus, + &[class*="focus"], + [class*="focus"] { + position: relative; + z-index: 5; + } } } diff --git a/WebContent/VAADIN/themes/valo/components/_datefield.scss b/WebContent/VAADIN/themes/valo/components/_datefield.scss index b1f3a78af6..1538681740 100644 --- a/WebContent/VAADIN/themes/valo/components/_datefield.scss +++ b/WebContent/VAADIN/themes/valo/components/_datefield.scss @@ -1,4 +1,4 @@ -@mixin valo-datefield ($primary-stylename: v-datefield) { +@mixin valo-datefield ($primary-stylename: v-datefield, $include-additional-styles: contains($v-included-additional-styles, datefield)) { .#{$primary-stylename} { position: relative; @@ -34,12 +34,42 @@ width: round($v-font-size * 6.5); } - .v-datefield-popup { + .#{$primary-stylename}-popup { @include valo-datefield-popup-style; } @include valo-datefield-calendarpanel-style; + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + .#{$primary-stylename}-textfield { + @include valo-textfield-borderless-style; + } + .#{$primary-stylename}-button { + border: none; + } + } + + .#{$primary-stylename}-align-right input { + text-align: right; + } + + .#{$primary-stylename}-align-center input { + text-align: center; + } + + .#{$primary-stylename}-small { + @include valo-datefield-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $border: null, $background-color: null, $states: normal); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-datefield-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $border: null, $background-color: null, $states: normal); + font-size: $v-font-size--large; + } + } + } @@ -64,7 +94,8 @@ $border : $v-textfield-border, $border-radius : $v-textfield-border-radius, $background-color : $v-textfield-background-color, - $primary-stylename : v-datefield + $primary-stylename : v-datefield, + $states : normal focus disabled ) { height: $unit-size; @@ -72,7 +103,7 @@ .#{$primary-stylename}-textfield { @include box-sizing(border-box); - @include valo-textfield-style($bevel: $bevel, $shadow: $shadow, $unit-size: $unit-size, $border: $border, $border-radius: $border-radius, $background-color: $background-color) ; + @include valo-textfield-style($bevel: $bevel, $shadow: $shadow, $unit-size: $unit-size, $border: $border, $border-radius: $border-radius, $background-color: $background-color, $states: $states) ; padding-left: $unit-size * 1.2; width: 100%; height: 100%; @@ -319,7 +350,7 @@ @include valo-datefield-calendarpanel-month-style; } - .v-datefield-year td.v-datefield-calendarpanel-month { + .#{$primary-stylename}-year td.#{$primary-stylename}-month { width: round($v-unit-size * 2); } @@ -350,12 +381,12 @@ background: $v-app-background-color; } - td.v-datefield-calendarpanel-time { + td.#{$primary-stylename}-time { width: 100%; font-size: ceil($v-font-size * 0.86); .v-label { - display: inline-block; + display: inline; margin: 0 0.1em; font-weight: 400; } diff --git a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss index 7f1be69553..6527e42ed7 100644 --- a/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss +++ b/WebContent/VAADIN/themes/valo/components/_dragwrapper.scss @@ -7,7 +7,8 @@ } .#{$primary-stylename}.v-active-drag-source { - visibility: hidden; + // This breaks file upload dragging (for some reason the ddwrapper gets this class when an active file drag is over it) + // visibility: hidden; } .#{$primary-stylename} { diff --git a/WebContent/VAADIN/themes/valo/components/_formlayout.scss b/WebContent/VAADIN/themes/valo/components/_formlayout.scss index 33191e4a20..25dbfbef28 100644 --- a/WebContent/VAADIN/themes/valo/components/_formlayout.scss +++ b/WebContent/VAADIN/themes/valo/components/_formlayout.scss @@ -1,4 +1,4 @@ -@mixin valo-formlayout ($primary-stylename: v-formlayout) { +@mixin valo-formlayout ($primary-stylename: v-formlayout, $include-additional-styles: contains($v-included-additional-styles, formlayout)) { @include valo-formlayout-spacing; @include valo-formlayout-margins; @@ -51,6 +51,11 @@ } + @if $include-additional-styles { + .#{$primary-stylename}.light { + @include valo-formlayout-light-style($primary-stylename); + } + } } diff --git a/WebContent/VAADIN/themes/valo/components/_label.scss b/WebContent/VAADIN/themes/valo/components/_label.scss index 502b640809..29d811fc9a 100644 --- a/WebContent/VAADIN/themes/valo/components/_label.scss +++ b/WebContent/VAADIN/themes/valo/components/_label.scss @@ -18,7 +18,7 @@ $v-letter-spacing--h3: 0 !default; $v-letter-spacing--h4: 0 !default; -@mixin valo-label ($primary-stylename: v-label) { +@mixin valo-label ($primary-stylename: v-label, $include-additional-styles: contains($v-included-additional-styles, label)) { .#{$primary-stylename}-undef-w { white-space: nowrap; @@ -101,31 +101,67 @@ $v-letter-spacing--h4: 0 !default; } } - .#{$primary-stylename}-large { - font-size: $v-font-size--large; - } - .#{$primary-stylename}-small { - font-size: $v-font-size--small; - } + @if $include-additional-styles { - .#{$primary-stylename}-bold { - font-weight: $v-font-weight + 200; - } + .#{$primary-stylename}-large { + font-size: $v-font-size--large; + } - .#{$primary-stylename}-light { - font-weight: $v-font-weight - 100; - @if $v-font-weight < 400 { - color: valo-font-color($v-app-background-color, .5); + .#{$primary-stylename}-small { + font-size: $v-font-size--small; } - } - .#{$primary-stylename}-align-right { - text-align: right; - } + .#{$primary-stylename}-bold { + font-weight: $v-font-weight + 200; + } + + .#{$primary-stylename}-light { + font-weight: $v-font-weight - 100; + @if $v-font-weight < 400 { + color: valo-font-color($v-app-background-color, .5); + } + } - .#{$primary-stylename}-align-center { - text-align: center; + .#{$primary-stylename}-align-right { + text-align: right; + } + + .#{$primary-stylename}-align-center { + text-align: center; + } + + .#{$primary-stylename}-spinner { + @include valo-spinner; + } + + .#{$primary-stylename}-success, + .#{$primary-stylename}-failure { + background: $v-textfield-background-color; + color: valo-font-color($v-textfield-background-color); + border: 2px solid $v-friendly-color; + border-radius: $v-border-radius; + padding: round($v-unit-size/5) round($v-unit-size/2) round($v-unit-size/5) round($v-unit-size); + font-weight: $v-font-weight + 100; + font-size: round($v-font-size * 0.95); + + &:before { + font-family: FontAwesome; + content: "\f00c"; + margin-right: .5em; + margin-left: round($v-unit-size/-2); + color: $v-friendly-color; + } + } + + .#{$primary-stylename}-failure { + border-color: $v-error-indicator-color; + + &:before { + content: "\f05e"; + color: $v-error-indicator-color; + } + } } } diff --git a/WebContent/VAADIN/themes/valo/components/_link.scss b/WebContent/VAADIN/themes/valo/components/_link.scss index 129ffcca2f..680659b8b6 100644 --- a/WebContent/VAADIN/themes/valo/components/_link.scss +++ b/WebContent/VAADIN/themes/valo/components/_link.scss @@ -3,7 +3,7 @@ $v-link-text-decoration: underline !default; $v-link-cursor: pointer !default; -@mixin valo-link ($primary-stylename: v-link) { +@mixin valo-link ($primary-stylename: v-link, $include-additional-styles: contains($v-included-additional-styles, link)) { .#{$primary-stylename} { @include valo-link-style; @@ -20,6 +20,16 @@ $v-link-cursor: pointer !default; cursor: inherit; } } + + @if $include-additional-styles { + .#{$primary-stylename}-small { + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + font-size: $v-font-size--large; + } + } } diff --git a/WebContent/VAADIN/themes/valo/components/_menubar.scss b/WebContent/VAADIN/themes/valo/components/_menubar.scss index 75b93b646f..e79e6898a9 100644 --- a/WebContent/VAADIN/themes/valo/components/_menubar.scss +++ b/WebContent/VAADIN/themes/valo/components/_menubar.scss @@ -1,4 +1,4 @@ -@mixin valo-menubar ($primary-stylename: v-menubar) { +@mixin valo-menubar ($primary-stylename: v-menubar, $include-additional-styles: contains($v-included-additional-styles, menubar)) { .#{$primary-stylename} { @include valo-button-static-style($states: normal, $vertical-centering: false); @@ -70,6 +70,18 @@ } } + + @if $include-additional-styles { + .#{$primary-stylename}-small { + @include valo-menubar-small-style($unit-size: $v-unit-size--small); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-borderless { + @include valo-menubar-borderless-style; + } + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_nativeselect.scss b/WebContent/VAADIN/themes/valo/components/_nativeselect.scss index 80e9ab8000..1b7469ed2b 100644 --- a/WebContent/VAADIN/themes/valo/components/_nativeselect.scss +++ b/WebContent/VAADIN/themes/valo/components/_nativeselect.scss @@ -23,6 +23,7 @@ @mixin valo-nativeselect-select-style { border: valo-border(); @include valo-gradient; + color: valo-font-color($v-background-color); &:focus { outline: none; diff --git a/WebContent/VAADIN/themes/valo/shared/_notification.scss b/WebContent/VAADIN/themes/valo/components/_notification.scss index cfe4c19599..3cfa446f7d 100644 --- a/WebContent/VAADIN/themes/valo/shared/_notification.scss +++ b/WebContent/VAADIN/themes/valo/components/_notification.scss @@ -1,11 +1,11 @@ $v-notification-title-color: $v-focus-color !default; -@mixin valo-notification ($primary-stylename: v-Notification) { +@mixin valo-notification ($primary-stylename: v-Notification, $include-additional-styles: contains($v-included-additional-styles, notification)) { // Positional offsets - .v-Notification { + .#{$primary-stylename} { &.v-position-top { top: $v-layout-spacing-vertical; } @@ -123,6 +123,78 @@ $v-notification-title-color: $v-focus-color !default; .#{$primary-stylename}.error { @include valo-notification-error-style; } + + + @if $include-additional-styles { + .#{$primary-stylename}.dark { + @include valo-notification-dark-style; + } + + .#{$primary-stylename}.bar { + @include valo-notification-bar-style; + } + + .#{$primary-stylename}.small { + @include valo-notification-small-style; + } + + .#{$primary-stylename}.closable { + @include valo-notification-closable-style; + + &.dark, + &.error, + &.system { + &:after { + color: #fff; + border-color: #fff; + border-color: rgba(255,255,255,.3); + } + &:active:after { + background-color: #fff; + color: #000; + } + } + + &.tray:after { + top: round($v-unit-size/2.3); + margin-top: 0; + } + } + + .#{$primary-stylename}.success, + .#{$primary-stylename}.failure { + background: #fff; + color: #555; + border: 2px solid $v-friendly-color; + + h1 { + color: $v-friendly-color; + font-weight: $v-font-weight + 100; + + &:before { + font-family: FontAwesome; + content: "\f00c"; + margin-right: .5em; + } + } + + &.bar { + margin: -2px !important; + } + } + + .#{$primary-stylename}.failure { + border-color: $v-error-indicator-color; + + h1 { + color: $v-error-indicator-color; + + &:before { + content: "\f05e"; + } + } + } + } } @@ -201,11 +273,11 @@ $v-notification-title-color: $v-focus-color !default; top: 0; @if $v-animations-enabled { - &.v-Notification-animate-in { + &[class*="animate-in"] { @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-down 200ms); } - &.v-Notification-animate-out { + &[class*="animate-out"] { @include animation(valo-placeholder-animate-out 200ms, valo-anim-slide-out-up 200ms); } } @@ -215,18 +287,18 @@ $v-notification-title-color: $v-focus-color !default; bottom: 0; @if $v-animations-enabled { - &.v-Notification-animate-in { + &[class*="animate-in"] { @include animation(valo-placeholder-animate-in 200ms, valo-anim-slide-in-up 200ms); } - &.v-Notification-animate-out { + &[class*="animate-out"] { @include animation(valo-placeholder-animate-out 200ms, valo-anim-slide-out-down 200ms); } } } } -@mixin valo-notification-system-style { +@mixin valo-notification-dark-style { background-color: #444; background-color: rgba(#444, .9); font-weight: $v-font-weight + 100; @@ -240,6 +312,10 @@ $v-notification-title-color: $v-focus-color !default; p { color: #e6e6e6; } +} + +@mixin valo-notification-system-style { + @include valo-notification-dark-style; // No need to underline the "click here" text, let's imply that the whole banner is clickable u { diff --git a/WebContent/VAADIN/themes/valo/components/_optiongroup.scss b/WebContent/VAADIN/themes/valo/components/_optiongroup.scss index 71c67cd9d8..a058ad4e85 100644 --- a/WebContent/VAADIN/themes/valo/components/_optiongroup.scss +++ b/WebContent/VAADIN/themes/valo/components/_optiongroup.scss @@ -1,13 +1,30 @@ -@mixin valo-optiongroup ($primary-stylename: v-optiongroup) { +@mixin valo-optiongroup ($primary-stylename: v-select-optiongroup, $include-additional-styles: contains($v-included-additional-styles, optiongroup)) { .v-radiobutton { @include valo-radiobutton-style; } - .v-select-optiongroup { + .#{$primary-stylename} { @include valo-optiongroup-style; } + + @if $include-additional-styles { + .#{$primary-stylename}-small { + @include valo-optiongroup-style($unit-size: $v-unit-size--small); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-optiongroup-style($unit-size: $v-unit-size--large); + font-size: $v-font-size--large; + } + + .#{$primary-stylename}-horizontal { + @include valo-optiongroup-horizontal; + } + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss b/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss index 1173ca3dbe..dbe2490826 100644 --- a/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss +++ b/WebContent/VAADIN/themes/valo/components/_orderedlayout.scss @@ -140,7 +140,7 @@ -@mixin valo-orderedlayout { +@mixin valo-orderedlayout ($include-additional-styles: contains($v-included-additional-styles, orderedlayout)) { .v-margin-top { padding-top: $v-layout-margin-top; @@ -163,10 +163,28 @@ height: $v-layout-spacing-vertical; } + @if $include-additional-styles { + .v-verticallayout-well, + .v-horizontallayout-well { + @include valo-panel-well-style; + @include valo-panel-adjust-content-margins; + } + + .v-verticallayout-card, + .v-horizontallayout-card { + @include valo-panel-style; + @include valo-panel-adjust-content-margins; + } + + .v-horizontallayout-wrapping { + @include valo-horizontallayout-wrapping-style; + } + } + } -@mixin valo-horizontallayout--wrapping { +@mixin valo-horizontallayout-wrapping-style { white-space: normal !important; & > .v-spacing + .v-slot, diff --git a/WebContent/VAADIN/themes/valo/components/_panel.scss b/WebContent/VAADIN/themes/valo/components/_panel.scss index 542c14ea64..6ccd5139da 100644 --- a/WebContent/VAADIN/themes/valo/components/_panel.scss +++ b/WebContent/VAADIN/themes/valo/components/_panel.scss @@ -1,10 +1,11 @@ $v-panel-background-color: scale-color(lighten($v-app-background-color, 5%), $saturation: -5%) !default; $v-panel-border: $v-border !default; -@mixin valo-panel ($primary-stylename: v-panel) { +@mixin valo-panel ($primary-stylename: v-panel, $include-additional-styles: contains($v-included-additional-styles, panel)) { .#{$primary-stylename} { @include valo-panel-style; + overflow: visible !important; } .#{$primary-stylename}-caption { @@ -19,6 +20,34 @@ $v-panel-border: $v-border !default; @include valo-panel-adjust-content-margins; } + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + @include valo-panel-borderless-style; + } + + .#{$primary-stylename}-well { + @include valo-panel-well-style; + } + + .#{$primary-stylename}-scroll-divider { + @include valo-panel-scroll-divider-style; + } + + .#{$primary-stylename}-caption.v-horizontallayout { + height: auto !important; + line-height: 0; + + .v-slot { + vertical-align: middle; + } + + .v-label { + line-height: $v-unit-size; + } + } + } + } @@ -41,7 +70,7 @@ $v-panel-border: $v-border !default; @mixin valo-panel-caption-style ( $background-color : $v-background-color, - $bevel : first($v-bevel), + $bevel : $v-bevel, $gradient : valo-gradient-style($v-gradient) valo-gradient-opacity($v-gradient)/4, $border : $v-panel-border ) { @@ -49,18 +78,43 @@ $v-panel-border: $v-border !default; padding: 0 round($v-unit-size/3); line-height: $v-unit-size - first-number($v-border); $bg: $background-color; - border-bottom: valo-border($border: $border, $color: $bg, $strength: 0.5); + + $shadow: null; + @if color-luminance($background-color) < color-luminance($v-background-color) - 10 { + $border-style: valo-border($border: $border, $color: $bg, $strength: 0.7); + $shadow: 0 0 0 first-number($border-style) first-color($border-style); + border-bottom: none; + margin-bottom: first-number($border-style); + + .v-ie8 & { + outline: first-number($border-style) solid first-color($border-style); + } + } @else { + border-bottom: valo-border($border: $border, $color: $v-background-color, $strength: 0.7); + } @include valo-gradient($color: $bg, $gradient: $gradient); color: valo-font-color($bg); font-weight: $v-caption-font-weight; font-size: $v-caption-font-size; - @include box-shadow(valo-bevel-and-shadow($background-color: $bg, $bevel: $bevel, $gradient: $gradient)); + @include box-shadow(valo-bevel-and-shadow($background-color: $bg, $bevel: $bevel, $shadow: $shadow, $gradient: $gradient)); text-shadow: valo-text-shadow(valo-font-color($bg), $bg, $v-bevel); } -@mixin valo-panel-well-style ($shadow: (0 1px 0 0 v-tint, join(inset, $v-shadow))) { +@mixin valo-panel-well-style ($shadow: false) { + @if $shadow == false { + $new-shadow: (); + @if list-of-lists($v-shadow) { + @each $part in $v-shadow { + $new-part: join(inset, $part); + $new-shadow: $new-shadow, $new-part; + } + } @else { + $new-shadow: join(inset, $v-shadow); + } + $shadow: 0 1px 0 0 v-tint, $new-shadow; + } $bg: scale-color(adjust-color($v-background-color, $lightness: -2%), $saturation: -1.5%); background: $bg; color: valo-font-color($bg); @@ -68,7 +122,7 @@ $v-panel-border: $v-border !default; border-radius: $v-border-radius; border: valo-border(); - > div > .v-panel-caption { + > div > [class*="-caption"] { background: transparent; @include box-shadow(none); } @@ -83,7 +137,7 @@ $v-panel-border: $v-border !default; border-radius: 0; @include box-shadow(none); - > div > .v-panel-caption { + > div > [class*="-caption"] { background: transparent; @include box-shadow(none); color: inherit; @@ -96,7 +150,7 @@ $v-panel-border: $v-border !default; @mixin valo-panel-scroll-divider-style ($border-width: max(1px, first-number($v-panel-border))) { - > .v-panel-captionwrap { + > [class*="-captionwrap"] { position: relative; z-index: 2; @@ -111,7 +165,7 @@ $v-panel-border: $v-border !default; } } - > .v-panel-content { + > [class*="-content"] { &:before { content: ""; position: absolute; diff --git a/WebContent/VAADIN/themes/valo/components/_richtextarea.scss b/WebContent/VAADIN/themes/valo/components/_richtextarea.scss index 702bda2ac4..2d32769898 100644 --- a/WebContent/VAADIN/themes/valo/components/_richtextarea.scss +++ b/WebContent/VAADIN/themes/valo/components/_richtextarea.scss @@ -48,7 +48,7 @@ $valo-richtextarea-use-font-awesome: true !default; "Toggle Strikethrough" "\f0cc", "Indent Right" "\f03c", "Indent Left" "\f03b", - "Insert Horizontal Rule" "—", + "Insert Horizontal Rule" "\2014", "Insert Ordered List" "\f0cb", "Insert Unordered List" "\f0ca", "Insert Image" "\f03e", diff --git a/WebContent/VAADIN/themes/valo/components/_slider.scss b/WebContent/VAADIN/themes/valo/components/_slider.scss index b4785a8471..123712a8ee 100644 --- a/WebContent/VAADIN/themes/valo/components/_slider.scss +++ b/WebContent/VAADIN/themes/valo/components/_slider.scss @@ -8,7 +8,7 @@ $_valo-slider-base-margin-vertical: round(($v-unit-size - $v-slider-track-size)/ $_valo-slider-base-margin-horizontal: round($v-slider-handle-width/2); -@mixin valo-slider ($primary-stylename: v-slider) { +@mixin valo-slider ($primary-stylename: v-slider, $include-additional-styles: contains($v-included-additional-styles, slider)) { // Round to an even number $v-slider-track-size: $v-slider-track-size + $v-slider-track-size%2; @@ -174,6 +174,13 @@ $_valo-slider-base-margin-horizontal: round($v-slider-handle-width/2); } } + + @if $include-additional-styles { + .#{$primary-stylename}-no-indicator { + @include valo-slider-no-indicator; + } + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_splitpanel.scss b/WebContent/VAADIN/themes/valo/components/_splitpanel.scss index e05eb08d16..cd709e1df9 100644 --- a/WebContent/VAADIN/themes/valo/components/_splitpanel.scss +++ b/WebContent/VAADIN/themes/valo/components/_splitpanel.scss @@ -1,6 +1,21 @@ -@mixin valo-splitpanel($primary-stylename : v-splitpanel) { - // No need for parent selector - @include valo-splitpanel-style($primary-stylename: $primary-stylename); +@mixin valo-splitpanel($primary-stylename : v-splitpanel, $include-additional-styles: contains($v-included-additional-styles, splitpanel)) { + .#{$primary-stylename}-horizontal { + @include valo-splitpanel-style($primary-stylename: $primary-stylename, $orientation: horizontal); + } + + .#{$primary-stylename}-vertical { + @include valo-splitpanel-style($primary-stylename: $primary-stylename, $orientation: vertical); + } + + @if $include-additional-styles { + .#{$primary-stylename}-horizontal.large { + @include valo-splitpanel-style($splitter-size: round($v-unit-size/3), $splitter-handle-visible: true, $orientation: horizontal); + } + + .#{$primary-stylename}-vertical.large { + @include valo-splitpanel-style($splitter-size: round($v-unit-size/3), $splitter-handle-visible: true, $orientation: vertical); + } + } } @@ -68,14 +83,14 @@ // Allow undefined/auto height for horizontal split - .#{$primary-stylename}-horizontal { - .#{$primary-stylename}-second-container { + .#{$primary-stylename}-horizontal > div { + > .#{$primary-stylename}-second-container { position: static !important; display: inline-block; vertical-align: top; } - .#{$primary-stylename}-first-container { + > .#{$primary-stylename}-first-container { display: inline-block; vertical-align: top; } @@ -94,76 +109,61 @@ $orientation: vertical horizontal ) { - @if contains($orientation, horizontal) { - .#{$primary-stylename}-hsplitter { - width: $splitter-size; - } - } - - @if contains($orientation, vertical) { - .#{$primary-stylename}-vsplitter { - height: $splitter-size; - } - } - $offset: round(($splitter-active-size - $splitter-size)/-2); @if contains($orientation, horizontal) { - .#{$primary-stylename}-hsplitter:after { - left: $offset; - right: $offset; - } - } + > div > .#{$primary-stylename}-hsplitter { + width: $splitter-size; - @if contains($orientation, vertical) { - .#{$primary-stylename}-vsplitter:after { - top: $offset; - bottom: $offset; - } - } + &:after { + left: $offset; + right: $offset; + } - @if contains($orientation, horizontal) or contains($orientation, vertical) { - .#{$primary-stylename}-hsplitter div, - .#{$primary-stylename}-vsplitter div { - &:before { - @include valo-button-style($shadow: $splitter-shadow); - height: auto; - padding: 0; - border-radius: 0; + div { + &:before { + @include valo-button-style($shadow: $splitter-shadow); + height: auto; + padding: 0; + border-radius: 0; + @include valo-gradient($color: $v-background-color, $direction: to right); + } + + @if $splitter-handle-visible { + &:after { + @include valo-splitpanel-splitter-handle-style($horizontal: true); + } + } } } - } - @if contains($orientation, horizontal) { - .#{$primary-stylename}-hsplitter div { - &:before { - $color: $v-background-color; - @include valo-gradient($color: $color, $direction: to right); - } + > div > .#{$primary-stylename}-second-container { + margin-left: $splitter-size; } } - @if $splitter-handle-visible { - .#{$primary-stylename}-vsplitter div, - .#{$primary-stylename}-hsplitter div { + @if contains($orientation, vertical) { + > div > .#{$primary-stylename}-vsplitter { + height: $splitter-size; + &:after { - @include valo-splitpanel-splitter-handle-style; + top: $offset; + bottom: $offset; } - } - @if contains($orientation, horizontal) { - .#{$primary-stylename}-hsplitter div { - &:after { - @include valo-splitpanel-splitter-handle-style($horizontal: true, $include-common: false); + div { + &:before { + @include valo-button-style($shadow: $splitter-shadow); + height: auto; + padding: 0; + border-radius: 0; } - } - } - } - @if contains($orientation, horizontal) { - &.#{$primary-stylename}-horizontal { - .#{$primary-stylename}-second-container { - margin-left: $splitter-size; + @if $splitter-handle-visible { + &:after { + @include valo-splitpanel-splitter-handle-style; + } + } } } } diff --git a/WebContent/VAADIN/themes/valo/components/_table.scss b/WebContent/VAADIN/themes/valo/components/_table.scss index deef084561..46318590d0 100644 --- a/WebContent/VAADIN/themes/valo/components/_table.scss +++ b/WebContent/VAADIN/themes/valo/components/_table.scss @@ -4,7 +4,7 @@ $v-table-border-color: null !default; $v-table-border-radius: 0 !default; $v-table-cell-padding-horizontal: round($v-unit-size/3) !default; //$v-table-cell-padding-horizontal-edge: round($v-unit-size/2.5) !default; -$v-table-resizer-width: round($v-unit-size/5) !default; +$v-table-resizer-width: round($v-unit-size/4.5) !default; $v-table-sort-indicator-width: round($v-unit-size/2) !default; $v-table-header-font-size: round($v-font-size * 0.86) !default; $v-table-background-color: null !default; @@ -60,7 +60,7 @@ $v-table-background-color: null !default; } -@mixin valo-table ($primary-stylename: v-table) { +@mixin valo-table ($primary-stylename: v-table, $include-additional-styles: contains($v-included-additional-styles, table)) { $background-color: $v-table-background-color or valo-table-background-color(); $border-color: $v-table-border-color or first-color(valo-border($color: $background-color, $strength: 0.8)); @@ -72,9 +72,9 @@ $v-table-background-color: null !default; color: valo-font-color($v-background-color); } - .v-table-header table, - .v-table-footer table, - .v-table-table { + .#{$primary-stylename}-header table, + .#{$primary-stylename}-footer table, + .#{$primary-stylename}-table { @include box-shadow(0 0 0 $v-table-border-width $border-color); .v-ie8 & { @@ -155,13 +155,14 @@ $v-table-background-color: null !default; cursor: col-resize; position: absolute; top: 0; - right: 0; + right: round($v-table-resizer-width / -2); z-index: 1; } .#{$primary-stylename}-cell-content { border-left: $v-table-border-width solid $border-color; overflow: hidden; + height: $v-table-row-height; &:first-child { border-left: none; @@ -177,10 +178,15 @@ $v-table-background-color: null !default; .#{$primary-stylename}-cell-wrapper { line-height: 1; + min-height: $v-table-row-height; $vertical-padding: round(($v-table-row-height - $v-font-size)/2); padding: $vertical-padding $v-table-cell-padding-horizontal; @include box-sizing(border-box); margin-right: 0 !important; + + > .v-widget { + margin: round($vertical-padding / -2) round($v-table-cell-padding-horizontal / -2); + } } .#{$primary-stylename}-body { @@ -287,12 +293,13 @@ $v-table-background-color: null !default; } .#{$primary-stylename}-focus-slot-right { - border-right: 2px solid rgba($v-focus-color, .5); + border-right: $v-table-border-width + 2px solid $v-focus-color; + right: -$v-table-border-width - 1px; } .#{$primary-stylename}-focus-slot-left { - border-left: 2px solid rgba($v-focus-color, .5); - left: 0; + border-left: $v-table-border-width + 2px solid $v-focus-color; + left: -$v-table-border-width; right: auto; margin-left: 0 !important; } @@ -429,6 +436,7 @@ $v-table-background-color: null !default; content: ""; display: block; position: absolute; + z-index: 1; height: $v-table-row-height + $v-table-border-width; left: 0; right: 0; @@ -466,6 +474,44 @@ $v-table-background-color: null !default; line-height: 0; } + + + + @if $include-additional-styles { + .#{$primary-stylename}-no-stripes { + @include valo-table-no-stripes-style; + } + + .#{$primary-stylename}-no-vertical-lines { + @include valo-table-no-vertical-lines-style; + } + + .#{$primary-stylename}-no-horizontal-lines { + @include valo-table-no-horizontal-lines-style; + } + + .#{$primary-stylename}-no-header { + @include valo-table-no-header-style; + } + + .#{$primary-stylename}-borderless { + @include valo-table-borderless-style; + } + + .#{$primary-stylename}-compact, + .#{$primary-stylename}-small { + @include valo-table-spacing-style($row-height: round($v-table-row-height * $v-scaling-factor--small), $cell-padding-horizontal: round($v-table-cell-padding-horizontal / 2)); + } + + .#{$primary-stylename}-small { + font-size: $v-font-size--small; + + &.v-treetable .#{$primary-stylename}-cell-wrapper { + min-height: $v-font-size--small; + } + } + } + } @@ -588,8 +634,17 @@ $v-table-background-color: null !default; height: $row-height; } + .#{$primary-stylename}-cell-content { + height: $row-height; + } + .#{$primary-stylename}-cell-wrapper { padding: $vertical-padding $cell-padding-horizontal; + min-height: $row-height; + + > .v-widget { + margin: round($vertical-padding / -2) round($cell-padding-horizontal / -2); + } } .#{$primary-stylename}-header-cell-asc .#{$primary-stylename}-sort-indicator, @@ -610,6 +665,7 @@ $v-table-background-color: null !default; .#{$primary-stylename}-cell-wrapper { padding-left: 0; padding-right: 0; + min-height: $v-font-size; } .#{$primary-stylename}-cell-content { diff --git a/WebContent/VAADIN/themes/valo/components/_tabsheet.scss b/WebContent/VAADIN/themes/valo/components/_tabsheet.scss index 2e28174fa7..7f2421b5ff 100644 --- a/WebContent/VAADIN/themes/valo/components/_tabsheet.scss +++ b/WebContent/VAADIN/themes/valo/components/_tabsheet.scss @@ -51,7 +51,7 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default; -@mixin valo-tabsheet ($primary-stylename: v-tabsheet) { +@mixin valo-tabsheet ($primary-stylename: v-tabsheet, $include-additional-styles: contains($v-included-additional-styles, tabsheet)) { .#{$primary-stylename} { &:not(.v-has-width) { width: auto !important; @@ -119,6 +119,43 @@ $v-tabsheet-content-animation-enabled: $v-animations-enabled !default; } } + + @if $include-additional-styles { + .#{$primary-stylename}-equal-width-tabs { + @include valo-tabsheet-equal-width-tabs-style($flex: false); + } + + .#{$primary-stylename}-framed { + @include valo-tabsheet-framed-style; + } + + .#{$primary-stylename}-centered-tabs { + @include valo-tabsheet-align-tabs-style($align: center); + } + + .#{$primary-stylename}-right-aligned-tabs { + @include valo-tabsheet-align-tabs-style($align: right); + } + + .#{$primary-stylename}-padded-tabbar { + @include valo-tabsheet-padded-tabbar-style; + } + + .#{$primary-stylename}-icons-on-top { + @include valo-tabsheet-icons-on-top-style; + } + + .#{$primary-stylename}-compact-tabbar { + > .#{$primary-stylename}-tabcontainer-compact-tabbar .v-caption { + line-height: 1.8; + } + } + + .#{$primary-stylename}-only-selected-closable { + @include valo-tabsheet-only-selected-closable-style; + } + } + } diff --git a/WebContent/VAADIN/themes/valo/components/_textarea.scss b/WebContent/VAADIN/themes/valo/components/_textarea.scss index 3b610251d3..4c5d99b8e2 100644 --- a/WebContent/VAADIN/themes/valo/components/_textarea.scss +++ b/WebContent/VAADIN/themes/valo/components/_textarea.scss @@ -1,4 +1,4 @@ -@mixin valo-textarea ($primary-stylename: v-textarea) { +@mixin valo-textarea ($primary-stylename: v-textarea, $include-additional-styles: contains($v-included-additional-styles, textarea)) { .#{$primary-stylename} { @include valo-textarea-style; @@ -13,6 +13,31 @@ @include valo-textfield-error-style; } + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + @include valo-textfield-borderless-style; + } + + .#{$primary-stylename}-small { + @include valo-textarea-style($unit-size: $v-unit-size--small, $states: normal, $background-color: null, $border: null, $bevel: null, $shadow: null); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-textarea-style($unit-size: $v-unit-size--large, $states: normal, $background-color: null, $border: null, $bevel: null, $shadow: null); + font-size: $v-font-size--large; + } + + .#{$primary-stylename}-align-right { + text-align: right; + } + + .#{$primary-stylename}-align-center { + text-align: center; + } + } + } @@ -47,9 +72,9 @@ $shadow: $shadow, $states: $states); - //display: block; // Fixes extra white-space under the textarea element height: auto; resize: none; + white-space: pre-wrap; // Restore default, because .v-widget sets it to normal .v-ie8 &, .v-ie9 & { diff --git a/WebContent/VAADIN/themes/valo/components/_textfield.scss b/WebContent/VAADIN/themes/valo/components/_textfield.scss index c314a0c855..75cfc5ef85 100644 --- a/WebContent/VAADIN/themes/valo/components/_textfield.scss +++ b/WebContent/VAADIN/themes/valo/components/_textfield.scss @@ -1,4 +1,5 @@ $v-textfield-background-color: if(is-dark-color($v-app-background-color), darken($v-app-background-color, 4%), lighten($v-app-background-color, 8%)) !default; +$v-textfield-background-color--readonly: $v-app-background-color; $v-textfield-bevel: inset 0 1px 0 v-shade !default; $v-textfield-shadow: 0 1px 0 (v-tint 2) !default; $v-textfield-font-weight: 400 !default; @@ -8,8 +9,51 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default; +@mixin valo-textfield ($primary-stylename: v-textfield, $include-additional-styles: contains($v-included-additional-styles, textfield)) { + .#{$primary-stylename} { + @include valo-textfield-style; + width: $v-default-field-width; + } + + .#{$primary-stylename}-readonly { + @include valo-textfield-readonly-style; + } + + .#{$primary-stylename}-error { + @include valo-textfield-error-style; + } + + + @if $include-additional-styles { + .#{$primary-stylename}-borderless { + @include valo-textfield-borderless-style; + } + + .#{$primary-stylename}-small { + @include valo-textfield-style($unit-size: $v-unit-size--small, $states: normal, $background-color: null, $border: null, $gradient: null, $bevel: null, $shadow: null); + font-size: $v-font-size--small; + } + + .#{$primary-stylename}-large { + @include valo-textfield-style($unit-size: $v-unit-size--large, $states: normal, $background-color: null, $border: null, $gradient: null, $bevel: null, $shadow: null); + font-size: $v-font-size--large; + } + + @include valo-textfield-inline-icon($stylenames: inline-icon); + @include valo-textfield-inline-icon($stylenames: inline-icon small, $unit-size: $v-unit-size--small, $font-size: $v-font-size--small); + @include valo-textfield-inline-icon($stylenames: inline-icon large, $unit-size: $v-unit-size--large, $font-size: $v-font-size--large); + + .#{$primary-stylename}-align-right { + text-align: right; + } + .#{$primary-stylename}-align-center { + text-align: center; + } + } + +} @@ -94,8 +138,7 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default; } // TODO allow parent selector to be used in interpolation - &.v-textfield-prompt, - &.v-textarea-prompt { + &[class*="prompt"] { @include valo-textfield-prompt-style($background-color); } @@ -134,29 +177,13 @@ $v-textfield-disabled-opacity: $v-disabled-opacity !default; @mixin valo-textfield-readonly-style { - background: transparent; + background: $v-textfield-background-color--readonly; + color: valo-font-color($v-textfield-background-color--readonly) @include box-shadow(none); &:focus { - @include valo-focus-style($include-box-shadow: true); - } -} - - -@mixin valo-textfield ($primary-stylename: v-textfield) { - - .#{$primary-stylename} { - @include valo-textfield-style; - width: $v-default-field-width; - } - - .#{$primary-stylename}-readonly { - @include valo-textfield-readonly-style; + box-shadow: none; + border-color: first-color(valo-border($v-textfield-border, $v-textfield-background-color--readonly)); } - - .#{$primary-stylename}-error { - @include valo-textfield-error-style; - } - } diff --git a/WebContent/VAADIN/themes/valo/components/_tree.scss b/WebContent/VAADIN/themes/valo/components/_tree.scss index 9ac2f7e43d..7e00f4ec09 100644 --- a/WebContent/VAADIN/themes/valo/components/_tree.scss +++ b/WebContent/VAADIN/themes/valo/components/_tree.scss @@ -51,7 +51,6 @@ $v-tree-expand-animation-enabled: false !default; opacity: 0; .v-ie8 & { - content: "+"; position: static; margin-left: -1.9em; vertical-align: top; @@ -72,6 +71,9 @@ $v-tree-expand-animation-enabled: false !default; overflow: hidden; white-space: nowrap; + // Mainly to satisty IE8 (doesn't harm other browsers) + vertical-align: top; + & > div { display: inline-block; width: 100%; @@ -116,11 +118,12 @@ $v-tree-expand-animation-enabled: false !default; &:after { content: ""; - display: inline-block; + display: block; vertical-align: top; position: absolute; z-index: 1; left: 0; + margin-top: -$v-tree-row-height; width: 100%; height: $v-tree-row-height; border-radius: $v-border-radius; @@ -153,8 +156,8 @@ $v-tree-expand-animation-enabled: false !default; @include valo-tree-expanded-icon-style(true); } - .#{$primary-stylename}-node-leaf > .#{$primary-stylename}-node-caption > div:before, - .v-ie8 & .#{$primary-stylename}-node-leaf:before { + .#{$primary-stylename}-node-leaf:before, + .#{$primary-stylename}-node-leaf > .#{$primary-stylename}-node-caption > div:before { visibility: hidden; } diff --git a/WebContent/VAADIN/themes/valo/components/_treetable.scss b/WebContent/VAADIN/themes/valo/components/_treetable.scss index 0423b37ab1..9a80fc6aa9 100644 --- a/WebContent/VAADIN/themes/valo/components/_treetable.scss +++ b/WebContent/VAADIN/themes/valo/components/_treetable.scss @@ -8,6 +8,10 @@ padding-right: 0; } + [class*="cell-wrapper"] { + min-height: $v-font-size; + } + [class*="caption-container"] { padding-left: $v-table-cell-padding-horizontal; } @@ -33,9 +37,10 @@ .#{$primary-stylename}-treespacer { display: inline-block; position: absolute; - width: round($v-unit-size/2); + width: round($v-unit-size/2) !important; margin-left: round($v-unit-size/-2) - round($v-table-cell-padding-horizontal/2); text-align: center; + cursor: pointer; } .#{$primary-stylename}-node-closed:before { diff --git a/WebContent/VAADIN/themes/valo/components/_upload.scss b/WebContent/VAADIN/themes/valo/components/_upload.scss index 103c21b6fe..c54227c704 100644 --- a/WebContent/VAADIN/themes/valo/components/_upload.scss +++ b/WebContent/VAADIN/themes/valo/components/_upload.scss @@ -2,4 +2,15 @@ .#{$primary-stylename} .v-button { @include valo-widget-style; } + + .#{$primary-stylename}-immediate input[type="file"] { + @include opacity(0); + z-index: 2; + position: absolute; + right: 0; + height: $v-unit-size; + text-align: right; + border: none; + background: transparent; + } }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/valo/components/_valo-menu.scss b/WebContent/VAADIN/themes/valo/components/_valo-menu.scss new file mode 100644 index 0000000000..507065d339 --- /dev/null +++ b/WebContent/VAADIN/themes/valo/components/_valo-menu.scss @@ -0,0 +1,465 @@ +$valo-menu-background-color: scale-color($v-app-background-color, $lightness: if(color-luminance($v-app-background-color) < 10, 15%, -70%)) !default; + +@mixin valo-menu ($bg: $valo-menu-background-color) { + + .valo-menu { + @include valo-menu-style($bg); + } + + .valo-menu-toggle { + display: none; + position: fixed; + z-index: 200; + $offset: floor(($v-unit-size - $v-unit-size * 0.8) / 2); + top: $offset; + left: $offset; + min-width: 0; + } + + .valo-menu-part { + border-left: valo-border($color: $bg, $strength: 0.6); + height: 100%; + padding-bottom: $v-unit-size; + overflow: auto; + + &:first-child { + border-left: none; + } + } + + .valo-menu-title, + .valo-menu-subtitle, + .valo-menu-item { + display: block; + line-height: inherit; + white-space: nowrap; + position: relative; + + .valo-menu-badge { + position: absolute; + right: round($v-unit-size/2); + } + } + + .valo-menu-title { + @include valo-menu-title-style; + text-align: center; + + .v-menubar.v-menubar { + background: transparent; + border-color: first-color(valo-border($color: $v-selection-color)); + color: inherit; + @include box-shadow(none); + text-shadow: inherit; + } + + .v-menubar-menuitem { + background: transparent; + @include box-shadow(valo-bevel-and-shadow($bevel: $v-bevel, $background-color: $v-selection-color, $gradient: $v-gradient)); + text-shadow: inherit; + font-size: $v-font-size; + border-color: inherit; + } + + h1, .v-label-h1, + h2, .v-label-h2, + h3, .v-label-h3, + h4, .v-label-h4 { + margin-top: 0; + margin-bottom: 0; + color: inherit; + } + } + + .v-menubar-user-menu { + @include valo-menubar-borderless-style; + margin: round($v-unit-size/2) round($v-unit-size/5); + display: block; + text-align: center; + height: auto; + color: inherit; + + > .v-menubar-menuitem { + color: inherit; + white-space: normal; + line-height: 1.4; + + img.v-icon { + width: round($v-unit-size * 1.5); + height: round($v-unit-size * 1.5); + border-radius: ceil($v-unit-size * 1.5 / 2); + box-shadow: valo-bevel-and-shadow($bevel: null, $shadow: $v-shadow); + display: block; + margin: 0 auto .3em; + } + } + + .v-menubar-menuitem-selected { + background: transparent; + } + } + + .valo-menu-subtitle { + @include valo-menu-subtitle-style($bg); + + .valo-menu-badge { + color: mix(valo-font-color($bg), $v-selection-color); + } + } + + .valo-menuitems { + display: block; + } + + .valo-menu-item { + @include valo-menu-item-style($bg); + } + + .valo-menu-part.large-icons { + @include valo-menu-large-icons-style($bg); + } + + .valo-menu-logo { + @include valo-menu-logo-style; + } + + @include valo-menu-responsive; + +} + + +@mixin valo-menu-responsive { + .v-ui { + @include width-range($min: 801px, $max: 1100px) { + .valo-menu-part { + @include valo-menu-large-icons-style($valo-menu-background-color); + } + } + + @include width-range($max: 800px) { + padding-top: $v-unit-size; + -webkit-box-sizing: border-box; + box-sizing: border-box; + + .v-loading-indicator { + top: $v-unit-size; + } + + > .v-widget { + position: relative !important + } + + .valo-menu { + border-right: none; + } + + .valo-menu-toggle { + display: inline-block; + } + + .valo-menu-title { + position: fixed; + z-index: 100; + top: 0; + left: 0; + right: 0; + height: $v-unit-size !important; + padding-top: 0; + padding-bottom: 0; + } + + .valo-menu .v-menubar-user-menu { + position: fixed; + z-index: 100; + top: 0; + right: 0; + margin: 0; + padding: 0; + height: $v-unit-size; + color: valo-font-color($v-selection-color, 0.5); + + .v-menubar-menuitem { + line-height: $v-unit-size - 1px; + } + + img.v-icon { + display: inline-block; + margin: 0 round($v-unit-size / 6) 0 0; + width: round($v-unit-size / 2); + height: round($v-unit-size / 2); + border-radius: ceil($v-unit-size / 4); + } + } + + .valo-menuitems { + @include valo-menu-style; + position: fixed; + z-index: 200; + top: $v-unit-size; + bottom: 0; + height: auto; + max-width: 100%; + overflow: auto; + padding: round($v-unit-size / 2) 0; + @include transform(translatex(-100%)); + @include transition(all 300ms); + } + + .valo-menu-visible .valo-menuitems { + @include transform(translatex(0%)); + } + } + + @include width-range($max: 500px) { + .valo-menu-toggle .v-button-caption { + display: none; + } + + .valo-menu .v-menubar-user-menu .v-menubar-menuitem-caption { + display: inline-block; + width: round($v-unit-size / 2); + overflow: hidden; + } + } + } +} + + + +@mixin valo-menu-style ($bg: $valo-menu-background-color) { + height: 100%; + @include linear-gradient(to left, (scale-color($bg, $lightness: valo-gradient-opacity()*-1) 0%, $bg round($v-unit-size/4)), $fallback: $bg); + color: valo-font-color($bg, 0.5); + font-size: round($v-font-size * 0.9); + line-height: round($v-unit-size * 0.8); + border-right: valo-border($color: $bg); + white-space: nowrap; +} + + + +@mixin valo-menu-title-style { + line-height: 1.2; + @include valo-gradient($color: $v-selection-color); + $font-color: valo-font-color($v-selection-color, 1); + color: $font-color; + text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $v-selection-color); + padding: round($v-unit-size/3) round($v-unit-size/2); + font-size: round($v-font-size * 0.9); + border-bottom: valo-border($color: $v-selection-color); + @include box-shadow(valo-bevel-and-shadow($shadow: $v-shadow)); +} + + + +@mixin valo-menu-subtitle-style ($bg: $valo-menu-background-color) { + color: valo-font-color($bg, 0.33); + margin: round($v-unit-size/5) 0 round($v-unit-size/5) round($v-unit-size/2); + border-bottom: valo-border($color: $bg, $strength: 0.5, $border: first-number($v-border) solid v-tone); +} + + + +@mixin valo-menu-item-style ($bg: $valo-menu-background-color) { + $font-color: valo-font-color($bg, 0.5); + outline: none; + font-weight: $v-font-weight + 100; + padding: 0 round($v-unit-size) 0 round($v-unit-size/2); + cursor: pointer; + position: relative; + text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $bg, $offset: -2px); + @include transition(background-color 300ms, color 60ms); + + $diff: color-luminance($bg) - color-luminance($v-selection-color); + $active-color: $v-selection-color; + @if abs($diff) < 30 { + $active-color: lighten($v-selection-color, 10%); + } + + [class*="caption"] { + vertical-align: middle; + display: inline-block; + width: 90%; + max-width: 15em; + padding-right: round($v-unit-size/2); + text-overflow: ellipsis; + overflow: hidden; + } + + &.selected { + background: if(is-dark-color($bg), darken($bg, 3%), lighten($bg, 5%)); + + .v-icon { + color: $active-color; + } + + [class*="badge"] { + @include valo-badge-style($states: active, $active-color: $active-color); + } + } + + &:focus, + &:hover, + &.selected { + color: valo-font-color($bg, 1); + } + + // Font icons + span.v-icon { + min-width: 1em; + margin-right: round($v-unit-size/2); + text-align: center; + vertical-align: middle; + + @if $v-gradient { + -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(black), to(rgba(0, 0, 0, 0.75))); + } + + + span { + margin-left: 0; + } + } + + [class*="badge"] { + @include valo-badge-style($states: inactive, $background-color: lighten($bg, 5%)); + } +} + + + + +@mixin valo-badge-style ($states: inactive active, $background-color: null, $active-color: $v-selection-color) { + @if contains($states, inactive) { + background-color: $background-color; + @include transition(background-color 300ms); + line-height: 1; + padding: round($v-unit-size/9) round($v-unit-size/6); + min-width: round($v-font-size/1.5); + text-align: center; + top: (round($v-unit-size * 0.8) - round($v-font-size * 0.9) - round($v-unit-size/9) * 2) / 2; + border-radius: $v-border-radius; + } + + @if contains($states, active) { + @include valo-gradient($color: $active-color); + color: valo-font-color($active-color); + } +} + + + +@mixin valo-menu-large-icons-style ($bg: darken($valo-menu-background-color, 4%)) { + background-color: $bg; + min-width: $v-unit-size * 2; + max-width: $v-unit-size * 3; + + .valo-menu-title { + font-size: round($v-font-size * 0.75); + + .v-label-undef-w { + white-space: normal; + } + } + + .v-menubar-user-menu { + margin-left: 0; + margin-right: 0; + font-size: round($v-font-size * 0.7); + + img.v-icon { + width: round($v-unit-size/1.3); + height: round($v-unit-size/1.3); + } + } + + [class*="subtitle"] { + margin: round($v-unit-size/4) 0 0; + padding: round($v-unit-size/5) round($v-unit-size/1.5) round($v-unit-size/5) round($v-unit-size/4); + line-height: 1; + border: none; + text-overflow: ellipsis; + overflow: hidden; + background: darken($bg, 6%); + font-size: round($v-font-size * 0.8); + box-shadow: valo-bevel-and-shadow($shadow: $v-shadow); + + [class*="badge"] { + right: round($v-unit-size/4); + } + + + .valo-menu-item { + border-top: none; + } + } + + .valo-menu-item { + display: block; + font-size: round($v-font-size * 1.6); + line-height: 1; + padding: round($v-unit-size/3); + text-align: center; + border-top: valo-border($color: $bg, $strength: 0.2, $border: first-number($v-border) solid v-tone); + + &:first-child { + border-top: none; + } + + [class*="caption"] { + display: block; + width: auto; + margin: .3em 0 0; + padding: 0; + font-size: round($v-font-size * 0.7); + line-height: 1.3; + } + + .v-icon { + margin: 0; + } + + span.v-icon { + opacity: 0.8; + } + + &.selected { + background: if(is-dark-color($bg), darken($bg, 3%), lighten($bg, 5%)); + + .v-icon { + opacity: 1; + } + + [class*="badge"] { + border-color: darken($bg, 3%); + } + } + + [class*="badge"] { + padding-left: round($v-unit-size/9); + padding-right: round($v-unit-size/9); + top: round($v-unit-size/5); + right: round($v-unit-size/5); + border: 2px solid $bg; + } + } +} + + + +@mixin valo-menu-logo-style { + display: block; + overflow: hidden; + width: round($v-unit-size * 1.2) !important; + height: round($v-unit-size * 1.2); + border-radius: $v-border-radius; + text-align: center; + @include valo-gradient($color: $v-selection-color); + color: valo-font-color($v-selection-color, 1); + font-size: round($v-unit-size/1.5); + line-height: round($v-unit-size * 1.2); + margin: round($v-unit-size/2) auto; + @include box-shadow(valo-bevel-and-shadow($shadow: $v-shadow)); + + &:focus { + outline: none; + } +} diff --git a/WebContent/VAADIN/themes/valo/components/_window.scss b/WebContent/VAADIN/themes/valo/components/_window.scss index d866ce2584..97859a62b2 100644 --- a/WebContent/VAADIN/themes/valo/components/_window.scss +++ b/WebContent/VAADIN/themes/valo/components/_window.scss @@ -125,7 +125,6 @@ $v-window-modality-curtain-background-color: #222 !default; line-height: $v-unit-size - 3px; text-align: center; cursor: pointer; - font-family: FontAwesome; font-size: round($v-font-size * 1.3); color: valo-font-color($v-window-background-color, .4); diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot Binary files differindex 5d20d91633..5d20d91633 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf Binary files differindex 2109c958e3..2109c958e3 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff Binary files differindex 1205787b0e..1205787b0e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Bold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot Binary files differindex 1f639a15ff..1f639a15ff 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf Binary files differindex 242d6b25c3..242d6b25c3 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff Binary files differindex ed760c0628..ed760c0628 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-BoldItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot Binary files differindex 1e29ad5954..1e29ad5954 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf Binary files differindex 6b9118ee35..6b9118ee35 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff Binary files differindex a7b99d2552..a7b99d2552 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot Binary files differindex 77184af422..77184af422 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf Binary files differindex 26a07e9392..26a07e9392 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff Binary files differindex 45395d1bbe..45395d1bbe 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-ExtraBoldItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot Binary files differindex 0c8a0ae06e..0c8a0ae06e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf Binary files differindex 12d25d9a73..12d25d9a73 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff Binary files differindex ff652e6435..ff652e6435 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Italic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot Binary files differindex 14868406aa..14868406aa 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf Binary files differindex 63af664cde..63af664cde 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff Binary files differindex e786074813..e786074813 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Light-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot Binary files differindex 8f445929ff..8f445929ff 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf Binary files differindex 01dda2858a..01dda2858a 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff Binary files differindex 43e8b9e6cc..43e8b9e6cc 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-LightItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot Binary files differindex 6bbc3cf58c..6bbc3cf58c 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf Binary files differindex c537f8382a..c537f8382a 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff Binary files differindex e231183dce..e231183dce 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Regular-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot Binary files differindex d8375dd0ab..d8375dd0ab 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf Binary files differindex b3290843a7..b3290843a7 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff Binary files differindex 28d6adee03..28d6adee03 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-Semibold-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot Binary files differindex 0ab1db22e6..0ab1db22e6 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.eot diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf Binary files differindex d2d6318f66..d2d6318f66 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.ttf diff --git a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff Binary files differindex d4dfca402e..d4dfca402e 100644..100755 --- a/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff +++ b/WebContent/VAADIN/themes/valo/fonts/open-sans/OpenSans-SemiboldItalic-webfont.woff diff --git a/WebContent/VAADIN/themes/valo/optional/_common-stylenames.scss b/WebContent/VAADIN/themes/valo/optional/_common-stylenames.scss deleted file mode 100644 index 09d29b7d9f..0000000000 --- a/WebContent/VAADIN/themes/valo/optional/_common-stylenames.scss +++ /dev/null @@ -1,441 +0,0 @@ -// Common styles for components -// About 90KB of CSS output - -@import "valo-menu"; - -@mixin valo-common-stylenames { - - $v-scaling-factor--small: 0.8 !default; - $v-scaling-factor--large: 1.2 !default; - - $v-unit-size--small: ceil($v-unit-size * $v-scaling-factor--small); - $v-unit-size--large: ceil($v-unit-size * $v-scaling-factor--large); - - $v-font-size--small: ceil($v-font-size * $v-scaling-factor--small); - $v-font-size--large: ceil($v-font-size * $v-scaling-factor--large); - - $v-friendly-color: #2c9720; - - - .v-button-primary { - @include valo-button-style($background-color: $v-selection-color); - $padding-width: round($v-unit-size/2); - padding: 0 $padding-width; - font-weight: bold; - $min-width: round($v-unit-size * 2.2); - min-width: $min-width; - - // IE8 + border-box + min-width == fail - .v-ie8 & { - min-width: $min-width - $padding-width*2; - } - } - - .v-button-friendly { - @include valo-button-style($background-color: $v-friendly-color); - } - - .v-button-danger { - @include valo-button-style($background-color: $v-error-indicator-color); - } - - .v-button-borderless { - @include valo-button-borderless-style; - } - - .v-button-borderless-colored { - @include valo-button-borderless-style($font-color: $v-selection-color); - } - - .v-button-quiet { - @include valo-button-quiet-style; - } - - .v-button-link { - @include valo-button-borderless-style; - @include valo-link-style; - } - - .v-button-small { - @include valo-button-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $background-color: null, $font-size: $v-font-size--small, $font-weight: null); - } - - .v-button-large { - @include valo-button-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $background-color: null, $font-size: $v-font-size--large, $font-weight: null); - } - - .v-button-icon-align-right { - @include valo-button-icon-align-right-style; - } - - .v-button-icon-align-top { - @include valo-button-icon-align-top-style; - } - - .v-button-icon-only { - width: $v-unit-size; - padding: 0; - - &.v-button-small { - width: $v-unit-size--small; - } - - &.v-button-large { - width: $v-unit-size--large; - } - - .v-button-caption { - display: none; - } - } - - .v-link-small { - font-size: $v-font-size--small; - } - - .v-link-large { - font-size: $v-font-size--large; - } - - .v-tabsheet-equal-width-tabs { - @include valo-tabsheet-equal-width-tabs-style($flex: false); - } - - .v-tabsheet-framed { - @include valo-tabsheet-framed-style; - } - - .v-tabsheet-centered-tabs { - @include valo-tabsheet-align-tabs-style($align: center); - } - - .v-tabsheet-right-aligned-tabs { - @include valo-tabsheet-align-tabs-style($align: right); - } - - .v-tabsheet-padded-tabbar { - @include valo-tabsheet-padded-tabbar-style; - } - - .v-tabsheet-icons-on-top { - @include valo-tabsheet-icons-on-top-style; - } - - .v-tabsheet-compact-tabbar { - > .v-tabsheet-tabcontainer-compact-tabbar .v-caption { - line-height: 1.8; - } - } - - .v-tabsheet-only-selected-closable { - @include valo-tabsheet-only-selected-closable-style; - } - - .v-panel-borderless { - @include valo-panel-borderless-style; - } - - .v-formlayout.light { - @include valo-formlayout-light-style; - } - - .v-textfield-borderless, - .v-textarea-borderless, - .v-datefield-borderless .v-datefield-textfield, - .v-filterselect-borderless .v-filterselect-input { - @include valo-textfield-borderless-style; - } - - .v-datefield-borderless .v-datefield-button, - .v-filterselect-borderless .v-filterselect-button { - border: none; - } - - .v-textfield-small { - @include valo-textfield-style($unit-size: $v-unit-size--small, $states: normal, $background-color: null, $border: null, $gradient: null, $bevel: null, $shadow: null); - font-size: $v-font-size--small; - } - - .v-textfield-large { - @include valo-textfield-style($unit-size: $v-unit-size--large, $states: normal, $background-color: null, $border: null, $gradient: null, $bevel: null, $shadow: null); - font-size: $v-font-size--large; - } - - @include valo-textfield-inline-icon($stylenames: inline-icon); - @include valo-textfield-inline-icon($stylenames: inline-icon small, $unit-size: $v-unit-size--small, $font-size: $v-font-size--small); - @include valo-textfield-inline-icon($stylenames: inline-icon large, $unit-size: $v-unit-size--large, $font-size: $v-font-size--large); - - .v-textarea-small { - @include valo-textarea-style($unit-size: $v-unit-size--small, $states: normal, $background-color: null, $border: null, $bevel: null, $shadow: null); - font-size: $v-font-size--small; - } - - .v-textarea-large { - @include valo-textarea-style($unit-size: $v-unit-size--large, $states: normal, $background-color: null, $border: null, $bevel: null, $shadow: null); - font-size: $v-font-size--large; - } - - .v-textfield-align-right, - .v-textarea-align-right, - .v-datefield-align-right input, - .v-filterselect-align-right input { - text-align: right; - } - - .v-textfield-align-center, - .v-textarea-align-center, - .v-datefield-align-center input, - .v-filterselect-align-center input { - text-align: center; - } - - .v-filterselect-small { - @include valo-combobox-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $gradient: null, $border: null, $border-radius: null, $background-color: null); - font-size: $v-font-size--small; - } - - .v-filterselect-large { - @include valo-combobox-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $gradient: null, $border: null, $border-radius: null, $background-color: null); - font-size: $v-font-size--large; - } - - .v-datefield-small { - @include valo-datefield-style($unit-size: $v-unit-size--small, $bevel: null, $shadow: null, $border: null, $background-color: null); - font-size: $v-font-size--small; - } - - .v-datefield-large { - @include valo-datefield-style($unit-size: $v-unit-size--large, $bevel: null, $shadow: null, $border: null, $background-color: null); - font-size: $v-font-size--large; - } - - .v-checkbox-small { - @include valo-checkbox-style($unit-size: $v-unit-size--small); - font-size: $v-font-size--small; - } - - .v-checkbox-large { - @include valo-checkbox-style($unit-size: $v-unit-size--large); - font-size: $v-font-size--large; - } - - .v-select-optiongroup-small { - @include valo-optiongroup-style($unit-size: $v-unit-size--small); - font-size: $v-font-size--small; - } - - .v-select-optiongroup-large { - @include valo-optiongroup-style($unit-size: $v-unit-size--large); - font-size: $v-font-size--large; - } - - .v-label-spinner { - @include valo-spinner; - } - - .v-panel-well { - @include valo-panel-well-style; - } - - .v-panel-borderless { - @include valo-panel-borderless-style; - } - - .v-panel-scroll-divider { - @include valo-panel-scroll-divider-style; - } - - .v-csslayout-well, - .v-verticallayout-well, - .v-horizontallayout-well { - @include valo-panel-well-style; - @include valo-panel-adjust-content-margins; - } - - .v-csslayout-card, - .v-verticallayout-card, - .v-horizontallayout-card { - @include valo-panel-style; - @include valo-panel-adjust-content-margins; - } - - .v-splitpanel-horizontal.large, - .v-splitpanel-vertical.large { - @include valo-splitpanel-style($splitter-size: round($v-unit-size/3), $splitter-handle-visible: true); - } - - .v-menubar-small { - @include valo-menubar-small-style($unit-size: $v-unit-size--small); - font-size: $v-font-size--small; - } - - .v-menubar-borderless { - @include valo-menubar-borderless-style; - } - - @include valo-component-group; - - .wrapping { - @include valo-horizontallayout--wrapping; - } - - .v-Notification.bar { - @include valo-notification-bar-style; - } - - .v-Notification.small { - @include valo-notification-small-style; - } - - .v-Notification.closable { - @include valo-notification-closable-style; - - &.error, - &.system { - &:after { - color: #fff; - border-color: #fff; - border-color: rgba(255,255,255,.3); - } - &:active:after { - background-color: #fff; - color: #000; - } - } - - &.tray:after { - top: round($v-unit-size/2.3); - margin-top: 0; - } - } - - .v-Notification.success, - .v-Notification.failure { - background: #fff; - color: #555; - border: 2px solid $v-friendly-color; - - h1 { - color: $v-friendly-color; - font-weight: $v-font-weight + 100; - - &:before { - font-family: FontAwesome; - content: "\f00c"; - margin-right: .5em; - } - } - - &.bar { - margin: -2px !important; - } - } - - .v-Notification.failure { - border-color: $v-error-indicator-color; - - h1 { - color: $v-error-indicator-color; - - &:before { - content: "\f05e"; - } - } - } - - .v-label-success, - .v-label-failure { - background: #fff; - color: #555; - border: 2px solid $v-friendly-color; - border-radius: $v-border-radius; - padding: round($v-unit-size/5) round($v-unit-size/2) round($v-unit-size/5) round($v-unit-size); - font-weight: $v-font-weight + 100; - font-size: round($v-font-size * 0.95); - - &:before { - font-family: FontAwesome; - content: "\f00c"; - margin-right: .5em; - margin-left: round($v-unit-size/-2); - color: $v-friendly-color; - } - } - - .v-label-failure { - border-color: $v-error-indicator-color; - - &:before { - content: "\f05e"; - color: $v-error-indicator-color; - } - } - - - .v-panel-caption.v-horizontallayout { - height: auto !important; - line-height: 0; - - .v-slot { - vertical-align: middle; - } - - .v-label { - line-height: $v-unit-size; - } - } - - - .v-select-optiongroup-horizontal { - @include valo-optiongroup-horizontal; - } - - - .v-table-no-stripes { - @include valo-table-no-stripes-style; - } - - .v-table-no-vertical-lines { - @include valo-table-no-vertical-lines-style; - } - - .v-table-no-horizontal-lines { - @include valo-table-no-horizontal-lines-style; - } - - .v-table-no-header { - @include valo-table-no-header-style; - } - - .v-table-borderless { - @include valo-table-borderless-style; - } - - .v-table-compact, - .v-table-small { - @include valo-table-spacing-style($row-height: round($v-table-row-height * $v-scaling-factor--small), $cell-padding-horizontal: round($v-table-cell-padding-horizontal / 2)); - } - - .v-table-small { - font-size: $v-font-size--small; - } - - - .v-accordion-borderless { - border: none; - border-radius: 0; - @include box-shadow(none); - - > .v-accordion-item { - border-radius: 0; - } - } - - .v-slider-no-indicator { - @include valo-slider-no-indicator; - } - - - @include valo-menu; - -} diff --git a/WebContent/VAADIN/themes/valo/optional/_valo-menu.scss b/WebContent/VAADIN/themes/valo/optional/_valo-menu.scss deleted file mode 100644 index f3377f232c..0000000000 --- a/WebContent/VAADIN/themes/valo/optional/_valo-menu.scss +++ /dev/null @@ -1,214 +0,0 @@ -$valo-menu-background-color: null !default; - -@mixin valo-menu { - - $bg-lightness: if(color-luminance($v-app-background-color) < 10, 15%, -70%); - $bg: $valo-menu-background-color or scale-color($v-app-background-color, $lightness: $bg-lightness); - $font-color: valo-font-color($bg, 0.5); - - .valo-menu { - height: 100%; - @include linear-gradient(to left, (scale-color($bg, $lightness: valo-gradient-opacity()*-1) 0%, $bg round($v-unit-size/4)), $fallback: $bg); - color: $font-color; - font-size: round($v-font-size * 0.9); - line-height: round($v-unit-size * 0.8); - border-right: valo-border($color: $bg); - white-space: nowrap; - - .valo-menu-part { - border-left: valo-border($color: $bg, $strength: 0.6); - height: 100%; - padding-bottom: $v-unit-size; - overflow: auto; - - &:first-child { - border-left: none; - } - } - - .valo-menu-title, - .valo-menu-subtitle, - .valo-menu-item { - display: block; - line-height: inherit; - white-space: nowrap; - position: relative; - - .valo-menu-badge { - position: absolute; - right: round($v-unit-size/2); - } - } - - .valo-menu-title { - line-height: 1.2; - @include valo-gradient($color: $v-selection-color); - $font-color: valo-font-color($v-selection-color, 1); - color: $font-color; - text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $v-selection-color); - padding: round($v-unit-size/3) round($v-unit-size/2); - font-size: round($v-font-size * 0.9); - border-bottom: valo-border($color: $v-selection-color); - @include box-shadow(valo-bevel-and-shadow($shadow: $v-shadow)); - - .v-menubar { - background: transparent; - border-color: first-color(valo-border($color: $v-selection-color)); - color: inherit; - @include box-shadow(none); - text-shadow: inherit; - } - - .v-menubar-menuitem { - background: transparent; - @include box-shadow(valo-bevel-and-shadow($bevel: $v-bevel, $background-color: $v-selection-color, $gradient: $v-gradient)); - text-shadow: inherit; - font-size: $v-font-size; - border-color: inherit; - } - } - - .valo-menu-subtitle { - color: valo-font-color($bg, 0.33); - margin: round($v-unit-size/5) 0 round($v-unit-size/5) round($v-unit-size/2); - border-bottom: valo-border($color: $bg, $strength: 0.5, $border: first-number($v-border) solid v-tone); - - .valo-menu-badge { - color: mix(valo-font-color($bg), $v-selection-color); - } - } - - .valo-menu-item { - outline: none; - font-weight: $v-font-weight + 100; - padding: 0 round($v-unit-size) 0 round($v-unit-size/2); - cursor: pointer; - position: relative; - text-shadow: valo-text-shadow($font-color: $font-color, $background-color: $bg, $offset: -2px); - @include transition(background-color 300ms, color 60ms); - - $diff: color-luminance($bg) - color-luminance($v-selection-color); - $active-color: $v-selection-color; - @if abs($diff) < 30 { - $active-color: lighten($v-selection-color, 10%); - } - - .valo-menu-item-caption { - vertical-align: middle; - display: inline-block; - width: 90%; - max-width: 15em; - padding-right: round($v-unit-size/2); - text-overflow: ellipsis; - overflow: hidden; - } - - &.selected { - background: darken($bg, 3%); - - .v-icon { - color: $active-color; - } - - .valo-menu-badge { - @include valo-gradient($color: $active-color); - color: valo-font-color($active-color); - } - } - - &:hover, - &.selected { - color: valo-font-color($bg, 1); - } - - // Font icons - span.v-icon { - min-width: 1em; - margin-right: round($v-unit-size/2); - text-align: center; - vertical-align: middle; - - + span { - margin-left: 0; - } - } - - .valo-menu-badge { - background: lighten($bg, 5%); - @include transition(background-color 300ms); - line-height: 1; - padding: round($v-unit-size/9) round($v-unit-size/6); - min-width: round($v-font-size/1.5); - text-align: center; - top: (round($v-unit-size * 0.8) - round($v-font-size * 0.9) - round($v-unit-size/9) * 2) / 2; - border-radius: $v-border-radius; - } - } - - .valo-menu-part.large-icons { - $bg: darken($bg, 4%); - background-color: $bg; - - .valo-menu-item { - font-size: $v-unit-size; - line-height: 1; - padding: round($v-unit-size/3); - min-width: $v-unit-size * 2; - max-width: $v-unit-size * 3; - text-align: center; - - .valo-menu-item-caption { - display: block; - width: auto; - margin: .3em 0 0; - padding: 0; - font-size: round($v-font-size * 0.7); - } - - .v-icon { - margin: 0; - } - - span.v-icon { - opacity: 0.8; - } - - &.selected { - background: darken($bg, 3%); - - .v-icon { - opacity: 1; - } - - .valo-menu-badge { - border-color: darken($bg, 3%); - } - } - - .valo-menu-badge { - padding-left: round($v-unit-size/9); - padding-right: round($v-unit-size/9); - top: round($v-unit-size/5); - right: round($v-unit-size/5); - border: 2px solid $bg; - } - } - } - - .valo-menu-logo { - display: block; - overflow: hidden; - width: round($v-unit-size * 1.2) !important; - height: round($v-unit-size * 1.2); - border-radius: $v-border-radius; - text-align: center; - @include valo-gradient($color: $v-selection-color); - color: valo-font-color($v-selection-color, 1); - font-size: round($v-unit-size/1.5); - line-height: round($v-unit-size * 1.2); - margin: round($v-unit-size/2) auto; - @include box-shadow(valo-bevel-and-shadow($shadow: $v-shadow)); - } - } - -} diff --git a/WebContent/VAADIN/themes/valo/shared/_global.scss b/WebContent/VAADIN/themes/valo/shared/_global.scss index 71d72b367c..7b7e63489a 100644 --- a/WebContent/VAADIN/themes/valo/shared/_global.scss +++ b/WebContent/VAADIN/themes/valo/shared/_global.scss @@ -1,18 +1,20 @@ @import "loading-indicator"; @import "contextmenu"; @import "overlay"; -@import "notification"; @import "tooltip"; -$v-app-background-color: $v-background-color !default; - - // Include global styles only once $valo-global-included: false !default; + @mixin valo-global { @if $valo-global-included == false { + // Version info for the debug window + .v-vaadin-version:after { + content: "@version@"; + } + // Core widget styles come before any other component (and are always included), // so that it has the least specificity @include valo-widget; @@ -304,7 +306,6 @@ $valo-shared-pathPrefix: null; font: inherit; font-weight: 400; line-height: inherit; - color: inherit; padding: round($v-unit-size/8); margin: 0; border-radius: $v-border-radius; diff --git a/WebContent/VAADIN/themes/valo/shared/_variables.scss b/WebContent/VAADIN/themes/valo/shared/_variables.scss index 8adc3667d3..b1c113b2cc 100644 --- a/WebContent/VAADIN/themes/valo/shared/_variables.scss +++ b/WebContent/VAADIN/themes/valo/shared/_variables.scss @@ -1,66 +1,7 @@ -// @category Common - // Color functions are used to calculate default font color @import "../util/color"; -// List of components to include in the theme compilation. The list can be modified to make -// the compiled theme smaller by removing unused components from the list. -// -// @usage -// // Remove the Calendar component styles from the output -// $v-included-components: remove($v-included-components, calendar); -$v-included-components: - absolutelayout, - accordion, - button, - calendar, - checkbox, - colorpicker, - combobox, - csslayout, - customcomponent, - customlayout, - datefield, - dragwrapper, - form, - formlayout, - grid, - gridlayout, - label, - link, - menubar, - nativebutton, - nativeselect, - notification, - optiongroup, - orderedlayout, - panel, - popupview, - progressbar, - slider, - splitpanel, - table, - tabsheet, - textfield, - textarea, - richtextarea, - tree, - treetable, - twincolselect, - upload, - window !default; - - -// Checks if a given component is included in the compilation. Used by the collection mixins that -// include all components, like valo-components and valo-components. -// @param $component-name {String} the name of the component to check -// @param $is-included {list} (Optional) the list of components which is checked -// @return {Boolean} true if the component is included in the compilation, false if not -@function v-is-included ($component-name, $is-included: $v-included-components) { - @return contains($is-included, $component-name); -} - // A static text that is shown while the application JavaScript is loaded and started $v-app-loading-text : "" !default; @@ -116,13 +57,81 @@ $v-default-field-width : $v-unit-size * 5 $v-error-indicator-color : #ed473b !default; $v-required-field-indicator-color : $v-error-indicator-color !default; +$v-friendly-color : #2c9720 !default; + +$v-scaling-factor--small : 0.8 !default; +$v-scaling-factor--large : 1.2 !default; +$v-unit-size--small : round($v-unit-size * $v-scaling-factor--small) !default; +$v-unit-size--large : round($v-unit-size * $v-scaling-factor--large) !default; +$v-font-size--small : round($v-font-size * $v-scaling-factor--small) !default; +$v-font-size--large : round($v-font-size * $v-scaling-factor--large) !default; -$valo-include-common-stylenames : true !default; +// List of components to include in the theme compilation. The list can be modified to make +// the compiled theme smaller by removing unused components from the list. +// +// @usage +// // Remove the Calendar component styles from the output +// $v-included-components: remove($v-included-components, calendar); +$v-included-components: + absolutelayout, + accordion, + button, + calendar, + checkbox, + colorpicker, + combobox, + csslayout, + customcomponent, + customlayout, + datefield, + dragwrapper, + form, + formlayout, + grid, + gridlayout, + label, + link, + menubar, + nativebutton, + nativeselect, + notification, + optiongroup, + orderedlayout, + panel, + popupview, + progressbar, + slider, + splitpanel, + table, + tabsheet, + textfield, + textarea, + richtextarea, + tree, + treetable, + twincolselect, + upload, + window, + valo-menu !default; + + +$v-included-additional-styles: $v-included-components !default; + + +// Checks if a given component is included in the compilation. Used by the collection mixins that +// include all components, like valo-components and valo-components. +// @param $component-name {String} the name of the component to check +// @param $is-included {list} (Optional) the list of components which is checked +// @return {Boolean} true if the component is included in the compilation, false if not +@function v-is-included ($component-name, $is-included: $v-included-components) { + @return contains($is-included, $component-name); +} + // A flag to note whether relative URL paths are relative to the currently parsed SCSS file or to the compilation root file. diff --git a/WebContent/VAADIN/themes/valo/util/_util.scss b/WebContent/VAADIN/themes/valo/util/_util.scss index 2f7b28b3ad..a510695560 100644 --- a/WebContent/VAADIN/themes/valo/util/_util.scss +++ b/WebContent/VAADIN/themes/valo/util/_util.scss @@ -25,3 +25,17 @@ -webkit-touch-callout: none; cursor: pointer; } + + + +@mixin width-range($min: 0, $max: null) { + &[width-range~="#{$min}-#{$max}"] { + @content; + } +} + +@mixin height-range($min: 0, $max: null) { + &[height-range~="#{$min}-#{$max}"] { + @content; + } +} diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index df46d8bc72..ced077138f 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -101,7 +101,7 @@ return value; }; - var fetchRootConfig = function() { + var fetchRootConfig = function(callback) { log('Fetching root config'); var url = getConfig('browserDetailsUrl'); if (!url) { @@ -141,6 +141,12 @@ r.open('POST', url, true); r.onreadystatechange = function (aEvt) { if (r.readyState == 4) { + // Save responseStatus so as Offline Applications know what happened + // when loading root configuration from server, and depending on the + // error status display an error message or the offline UI. + config.rootResponseStatus = r.status; + config.rootResponseText = r.responseText; + var text = r.responseText; if (r.status == 200){ log("Got root config response", text); @@ -166,6 +172,9 @@ appDiv.innerHTML = text; appDiv.style['overflow'] = 'auto'; } + + // Run the fetchRootConfig callback if present. + callback && callback(r); } }; // send parameters as POST data @@ -177,7 +186,10 @@ //Export public data var app = { - 'getConfig': getConfig + getConfig: getConfig, + // Used when the app was started in offline, so as it is possible + // to defer root configuration loading until network is available. + fetchRootConfig: fetchRootConfig }; apps[appId] = app; @@ -224,9 +236,17 @@ return app; }, clients: {}, + getAppIds: function() { + var ids = [ ]; + for (var id in apps) { + if (apps.hasOwnProperty(id)) { + ids.push(id); + } + } + return ids; + }, getApp: function(appId) { - var app = apps[appId]; - return app; + return apps[appId]; }, loadTheme: loadTheme, registerWidgetset: function(widgetset, callback) { diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index fb2ddbd998..9ca5be2bdf 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -118,11 +118,11 @@ <param-name>pushmode</param-name> <param-value>automatic</param-value> </init-param> - <async-supported>true</async-supported> <init-param> <param-name>org.atmosphere.cpr.scanClassPath</param-name> <param-value>false</param-value> </init-param> + <async-supported>true</async-supported> </servlet> <!-- For testing GAE - the deployment script changes this to use GAEVaadinServlet --> @@ -133,11 +133,11 @@ <param-name>UI</param-name> <param-value>com.vaadin.tests.integration.ServletIntegrationUI</param-value> </init-param> - <async-supported>true</async-supported> <init-param> <param-name>org.atmosphere.cpr.scanClassPath</param-name> <param-value>false</param-value> </init-param> + <async-supported>true</async-supported> </servlet> <servlet-mapping> diff --git a/WebContent/html-tests/BottomComponentScrollsUp.html b/WebContent/html-tests/BottomComponentScrollsUp.html new file mode 100644 index 0000000000..a264b38ba8 --- /dev/null +++ b/WebContent/html-tests/BottomComponentScrollsUp.html @@ -0,0 +1,96 @@ +<html> + +<head> +<title>Bottom component scroll when focus - test with plain html to see the default behaviour</title> +<link rel="stylesheet" type="text/css" href="./../VAADIN/themes/reindeer/styles.css"> + +<script> + +function setScrollOnPanel() { + var popups = document.getElementsByClassName("v-panel-content"); + popups[0].scrollTop = 756; + + console.log("popups[0]: " + popups[0].scrollTop); +} + +</script> + +</head> + +<body> + +<div id="runBottomComponentScrollsUp-1897366330-overlays" class="v-app reindeer v-overlay-container" aria-live="assertive" aria-label="This content is announced automatically and does not need to be navigated into." aria-relevant="additions"> + +<div class="v-tooltip" role="tooltip" aria-live="assertive" aria-relevant="additions" style="margin-left: 0px; margin-top: 0px; left: -4990px; top: -4990px; z-index: 20000; visibility: visible; position: absolute; overflow: visible;"> + +<div class="popupContent"><div><div class="v-errormessage" aria-hidden="true" style="display: none;"></div><div class="v-tooltip-text"> </div></div></div></div> + +<div class="v-window v-widget v-has-width v-has-height" role="dialog" aria-relevant="additions" aria-labelledby="gwt-uid-2" style="margin-left: 0px; margin-top: 0px; left: 400px; top: 19px; z-index: 10000; width: 300px; height: 300px; visibility: visible; position: absolute; overflow: visible; min-width: 66px; min-height: 52px;"> +<div class="popupContent"> +<div class="v-window-wrap"> + +<div tabindex="0" aria-label="Top of dialog"></div> + +<div class="v-window-outerheader"> +<div class="v-window-header" id="gwt-uid-2"> +<span class="v-assistive-device-only"></span> +<span class="v-assistive-device-only"></span> +</div> +</div> + +<div class="v-window-maximizebox" tabindex="0" role="button" aria-label="maximize button" id="28_window_maximizerestore"></div> +<div class="v-window-closebox" tabindex="0" role="button" aria-label="close button" id="28_window_close"></div> + +<div class="v-window-contents" style="padding-top: 37px; margin-top: -37px; padding-bottom: 15px; margin-bottom: -15px;"> +<div tabindex="0" class="v-scrollable" style="zoom: 1; position: relative;"> +<div class="v-panel v-widget v-has-width v-has-height" style="overflow: hidden; width: 100%; height: 100%; position: absolute; padding-top: 1px; padding-bottom: 1px;"> + +<div class="v-panel-captionwrap" style="margin-top: -1px;"> +<div class="v-panel-nocaption"><span></span> +</div> +</div> + +<div class="v-panel-content v-scrollable" tabindex="-1" style="position: relative;"> +<div class="v-verticallayout v-layout v-vertical v-widget v-has-width v-has-height" style="width: 100%; height: 1000px;"> + +<div class="v-expand" style="padding-top: 0px;"> + +<div class="v-slot" style="height: 50%; margin-top: 0px;"> +<div role="combobox" class="v-filterselect v-widget v-filterselect-prompt"> +<input type="text" class="v-filterselect-input" tabindex="0" style="width: 129px;"> +<div class="v-filterselect-button" aria-hidden="true" role="button"></div> +</div> +</div> + +<div class="v-slot v-align-center v-align-bottom" style="height: 50%;"> +<div tabindex="0" role="button" class="v-button v-widget v-has-height" style="height: 100px;" onclick="setScrollOnPanel();"> +<span class="v-button-wrap"><span class="v-button-caption">Press me</span></span> +</div> +</div> + +</div> + +</div> +</div> + +<div class="v-panel-deco" style="margin-bottom: -1px;"></div> + +</div> +</div> +</div> + +<div class="v-window-footer"> +<div class="v-window-resizebox"></div> +</div> + +<div tabindex="0" aria-label="Bottom of Dialog"></div> + +</div> +</div> +</div> + +</div> + +</body> + +</html>
\ No newline at end of file diff --git a/WebContent/html-tests/ComponentFocus.html b/WebContent/html-tests/ComponentFocus.html new file mode 100644 index 0000000000..0a822520e0 --- /dev/null +++ b/WebContent/html-tests/ComponentFocus.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title>Insert title here</title> + +<script type="text/javascript"> + +</script> + +</head> +<body> +<button onfocus="console.log('button focus');" onblur="console.log('button blur');">Focus me</button> +<textarea onfocus="console.log('textarea focus');" onblur="console.log('textarea blur');">Focus me too</textarea> +</body> +</html>
\ No newline at end of file diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index f02a1aebd7..2c27ad32cc 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -101,6 +101,7 @@ the Sass CSS preprocessor heavily, providing a variety of ways to customize the look and feel of your theme. See <a href="https://vaadin.com/wiki/-/wiki/Main/Valo+theme+-+Getting+started">the Valo theme tutorial</a> or <a href="https://vaadin.com/book/-/page/themes.valo.html">the Valo theme section</a> in Book of Vaadin for information on how to get started.</li> + <li>Support for changing theme on the fly</li> </ul> <p> diff --git a/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html index 613bb2cd41..cb317dd755 100644 --- a/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html +++ b/WebContent/statictestfiles/PopupViewInEmbeddedApplication.html @@ -11,7 +11,7 @@ </head> <body> - <script type="text/javascript" src="/VAADIN/vaadinBootstrap.js"></script> + <script type="text/javascript" src="../VAADIN/vaadinBootstrap.js"></script> <p>This is a static web page that contains an embedded Vaadin diff --git a/build.properties b/build.properties index 0c0e58cb53..bd31158a3e 100644 --- a/build.properties +++ b/build.properties @@ -5,6 +5,6 @@ vaadin.vendor=Vaadin Ltd vaadin.url=http://vaadin.com vaadin.java.version=1.6 vaadin.version=0.0.0.unversioned-development-build -vaadin.sass.version=0.9.8 -gwt.version=2.6.0.vaadin3 +vaadin.sass.version=0.9.9 +gwt.version=2.6.0.vaadin4 commons-io.version=2.4 diff --git a/build/ide.xml b/build/ide.xml index 0775a67505..c7183077a9 100755 --- a/build/ide.xml +++ b/build/ide.xml @@ -4,61 +4,98 @@ <property name="work.dir" location="work" /> <property file="build.properties" /> - <ivy:resolve log="download-only" file="client-compiler/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="client-compiler.deps" conf="ide" /> - <ivy:resolve log="download-only" file="server/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="server.deps" conf="ide" /> - <ivy:resolve log="download-only" file="client/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="client.deps" conf="ide" /> - <ivy:resolve log="download-only" file="shared/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="shared.deps" conf="ide" /> - <ivy:resolve log="download-only" file="uitest/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="uitest.deps" conf="ide" /> - <ivy:resolve log="download-only" file="buildhelpers/ivy.xml" /> - <ivy:cachepath pathid="buildhelpers.deps" /> - <ivy:resolve log="download-only" file="gwt/ivy.xml" conf="ide" /> - <ivy:cachepath pathid="gwt.deps" conf="ide" /> - - <path id="classpath"> - <path location="bin" /> - <path location="build/classes" /> - <path refid="client-compiler.deps" /> - <path refid="server.deps" /> - <path refid="shared.deps" /> - <path refid="uitest.deps" /> - <path refid="client.deps" /> - <path refid="buildhelpers.deps" /> - <path refid="gwt.deps" /> - <path location="server/src" /> - <path location="shared/src" /> - <path location="uitest/src" /> - <path location="client/src" /> - </path> - - <target name="theme-and-default-widgetset" depends="default-widgetset, themes, vaadinPush.js"> + <!-- Setting this to 0 disables the parallel compilation --> + <property name="threadsPerProcessor" value="1" /> + + <target name="resolve" unless="resolve.done"> + <ivy:resolve log="download-only" file="client-compiler/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="client-compiler.deps" conf="ide" /> + <ivy:resolve log="download-only" file="server/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="server.deps" conf="ide" /> + <ivy:resolve log="download-only" file="client/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="client.deps" conf="ide" /> + <ivy:resolve log="download-only" file="shared/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="shared.deps" conf="ide" /> + <ivy:resolve log="download-only" file="uitest/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="uitest.deps" conf="ide" /> + <ivy:resolve log="download-only" file="buildhelpers/ivy.xml" /> + <ivy:cachepath pathid="buildhelpers.deps" /> + <ivy:resolve log="download-only" file="gwt/ivy.xml" conf="ide" /> + <ivy:cachepath pathid="gwt.deps" conf="ide" /> + + <path id="classpath"> + <path location="bin" /> + <path location="build/classes" /> + <path refid="client-compiler.deps" /> + <path refid="server.deps" /> + <path refid="shared.deps" /> + <path refid="uitest.deps" /> + <path refid="client.deps" /> + <path refid="buildhelpers.deps" /> + <path refid="gwt.deps" /> + <path location="server/src" /> + <path location="shared/src" /> + <path location="uitest/src" /> + <path location="client/src" /> + </path> + <property name="resolve.done" value="true" /> </target> - <target name="themes"> - <antcall target="compile-theme"> - <param name="theme" value="base" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="runo" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="reindeer" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="chameleon" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="liferay" /> - </antcall> - <antcall target="compile-theme"> - <param name="theme" value="valo" /> - </antcall> + + <target name="theme-and-default-widgetset" depends="resolve"> + <!-- threadCount is ignored unless threadsPerProcessor is 0 --> + <parallel threadsPerProcessor="${threadsPerProcessor}" threadCount="1"> + <antcall target="default-widgetset" inheritRefs="true" /> + <antcall target="themes" inheritRefs="true" /> + <antcall target="vaadinPush.js" inheritRefs="true" /> + </parallel> + </target> + + <target name="themes" depends="resolve"> + <!-- threadCount is ignored unless threadsPerProcessor is 0 --> + <parallel threadsPerProcessor="${threadsPerProcessor}" threadCount="1"> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="base" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="runo" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="reindeer" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="chameleon" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="liferay" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="valo" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-dark" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-metro" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-flat" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-flatdark" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-facebook" /> + </antcall> + <antcall target="compile-theme" inheritRefs="true"> + <param name="theme" value="tests-valo-blueprint" /> + </antcall> + </parallel> </target> - <target name="compile-theme"> + <target name="compile-theme" depends="resolve"> <java classname="com.vaadin.buildhelpers.CompileTheme" failonerror="yes" fork="yes"> <classpath refid="classpath" /> <jvmarg value="-Djava.awt.headless=true" /> @@ -74,18 +111,18 @@ <target name="default-widgetset"> - <antcall target="compile-widgetset"> + <antcall target="compile-widgetset" inheritRefs="true"> <param name="widgetset" value="com.vaadin.DefaultWidgetSet" /> </antcall> </target> <target name="testing-widgetset"> - <antcall target="compile-widgetset"> + <antcall target="compile-widgetset" inheritRefs="true"> <param name="widgetset" value="com.vaadin.tests.widgetset.TestingWidgetSet" /> </antcall> </target> - <target name="compile-widgetset"> + <target name="compile-widgetset" depends="resolve"> <property name="module" value="${widgetset}" /> <property name="module.output.dir" location="WebContent/VAADIN/widgetsets" /> <property name="style" value="PRETTY" /> @@ -125,7 +162,7 @@ <jvmarg value="-Dgwt.persistentunitcache=false" /> </java> </target> - <target name="vaadinPush.js"> + <target name="vaadinPush.js" depends="resolve"> <ant antfile="${basedir}/push/build.xml" target="vaadinPush.js" dir="${basedir}/push" /> <property name="js.output.dir" location="WebContent" /> <property name="push.js.dir" location="${basedir}/push/result/js" /> diff --git a/buildhelpers/ivy.xml b/buildhelpers/ivy.xml index 9117721444..cf04bfdc5d 100644 --- a/buildhelpers/ivy.xml +++ b/buildhelpers/ivy.xml @@ -18,7 +18,6 @@ <conf name="build" /> <conf name="build-provided" /> <conf name="ide" visibility="private" /> - <conf name="test" /> </configurations> <publications> <artifact type="jar" /> diff --git a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java index 028880b2e1..dc2a676ab8 100644 --- a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java +++ b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -58,6 +58,10 @@ public class FetchReleaseNotesTickets { List<String> tickets = IOUtils.readLines(urlStream); for (String ticket : tickets) { + // Omit BOM + if (!ticket.isEmpty() && ticket.charAt(0) == 65279) { + ticket = ticket.substring(1); + } String[] fields = ticket.split("\t"); if ("id".equals(fields[0])) { // This is the header diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index 5519dd1aae..a6ca690a8a 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -639,13 +639,18 @@ public class ConnectorBundleLoaderFactory extends Generator { private void writeDelegateToWidget(TreeLogger logger, SplittingSourceWriter w, ConnectorBundle bundle) { - Set<Property> needsDelegateToWidget = bundle.getNeedsDelegateToWidget(); - for (Property property : needsDelegateToWidget) { - w.println("store.setDelegateToWidget(%s, \"%s\", \"%s\");", - getClassLiteralString(property.getBeanType()), - property.getName(), - property.getAnnotation(DelegateToWidget.class).value()); - + Map<JClassType, Set<Property>> needsDelegateToWidget = bundle + .getNeedsDelegateToWidget(); + for (Entry<JClassType, Set<Property>> entry : needsDelegateToWidget + .entrySet()) { + JClassType beanType = entry.getKey(); + for (Property property : entry.getValue()) { + w.println( + "store.setDelegateToWidget(%s, \"%s\", \"%s\");", + getClassLiteralString(beanType),// property.getBeanType()), + property.getName(), + property.getAnnotation(DelegateToWidget.class).value()); + } w.splitIfNeeded(); } } diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java index 8bbcac4ecb..e8a384298f 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -38,6 +38,7 @@ import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.NotFoundException; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.json.client.JSONValue; +import com.google.gwt.thirdparty.guava.common.collect.Sets; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; @@ -72,7 +73,7 @@ public class ConnectorBundle { private final Map<JClassType, Set<JMethod>> needsOnStateChange = new HashMap<JClassType, Set<JMethod>>(); private final Set<Property> needsProperty = new HashSet<Property>(); - private final Set<Property> needsDelegateToWidget = new HashSet<Property>(); + private final Map<JClassType, Set<Property>> needsDelegateToWidget = new HashMap<JClassType, Set<Property>>(); private ConnectorBundle(String name, ConnectorBundle previousBundle, Collection<TypeVisitor> visitors, @@ -567,23 +568,25 @@ public class ConnectorBundle { } } - public void setNeedsDelegateToWidget(Property property) { - if (!isNeedsDelegateToWidget(property)) { - needsDelegateToWidget.add(property); + public void setNeedsDelegateToWidget(Property property, JClassType type) { + if (!isNeedsDelegateToWidget(type)) { + needsDelegateToWidget.put(type, Sets.newHashSet(property)); + } else if (!needsDelegateToWidget.get(type).contains(property)) { + needsDelegateToWidget.get(type).add(property); } } - private boolean isNeedsDelegateToWidget(Property property) { - if (needsDelegateToWidget.contains(property)) { + private boolean isNeedsDelegateToWidget(JClassType type) { + if (needsDelegateToWidget.containsKey(type)) { return true; } else { return previousBundle != null - && previousBundle.isNeedsDelegateToWidget(property); + && previousBundle.isNeedsDelegateToWidget(type); } } - public Set<Property> getNeedsDelegateToWidget() { - return Collections.unmodifiableSet(needsDelegateToWidget); + public Map<JClassType, Set<Property>> getNeedsDelegateToWidget() { + return Collections.unmodifiableMap(needsDelegateToWidget); } public void setNeedsOnStateChangeHandler(JClassType type, JMethod method) { diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java index 6c242dfd74..a31dafe05c 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java @@ -45,25 +45,17 @@ public class FieldProperty extends Property { @Override public void writeSetterBody(TreeLogger logger, SourceWriter w, String beanVariable, String valueVariable) { - // Don't try to unbox Longs in javascript, as it's not supported. - // (#13692) - boolean shouldUnbox = !"long".equals(field.getType() - .getSimpleSourceName()); w.println("%s.@%s::%s = %s;", beanVariable, getBeanType() - .getQualifiedSourceName(), getName(), - shouldUnbox ? unboxValue(valueVariable) : valueVariable); + .getQualifiedSourceName(), getName(), unboxValue(valueVariable)); } @Override public void writeGetterBody(TreeLogger logger, SourceWriter w, String beanVariable) { - // Longs are not unboxed, as it's not supported. (#13692) - boolean shouldBox = !"long".equals(field.getType() - .getSimpleSourceName()); String value = String.format("%s.@%s::%s", beanVariable, getBeanType() .getQualifiedSourceName(), getName()); w.print("return "); - w.print(shouldBox ? boxValue(value) : value); + w.print(boxValue(value)); w.println(";"); } diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java index e3fee8d9ee..a77b523d14 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/WidgetInitVisitor.java @@ -59,7 +59,7 @@ public class WidgetInitVisitor extends TypeVisitor { .getAnnotation(DelegateToWidget.class); if (delegateToWidget != null) { // Generate meta data required for @DelegateToWidget - bundle.setNeedsDelegateToWidget(property); + bundle.setNeedsDelegateToWidget(property, stateType); // Find the delegate target method String methodName = DelegateToWidget.Helper diff --git a/client-compiler/src/com/vaadin/tools/CvalChecker.java b/client-compiler/src/com/vaadin/tools/CvalChecker.java index 2de7e10faa..e426c5c4e6 100644 --- a/client-compiler/src/com/vaadin/tools/CvalChecker.java +++ b/client-compiler/src/com/vaadin/tools/CvalChecker.java @@ -26,6 +26,7 @@ import java.net.URLConnection; import java.text.MessageFormat; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import java.util.prefs.Preferences; @@ -465,7 +466,8 @@ public final class CvalChecker { if (url != null) { try { - key = IOUtils.toString(url.openStream()); + key = readKeyFromFile(url, + computeMajorVersion(productVersion)); if (key != null && !(key = key.trim()).isEmpty()) { return key; } @@ -480,6 +482,22 @@ public final class CvalChecker { productTitle, null, null); } + String readKeyFromFile(URL url, int majorVersion) throws IOException { + String majorVersionStr = String.valueOf(majorVersion); + List<String> lines = IOUtils.readLines(url.openStream()); + String defaultKey = null; + for (String line : lines) { + String[] parts = line.split("\\s*=\\s*"); + if (parts.length < 2) { + defaultKey = parts[0].trim(); + } + if (parts[0].equals(majorVersionStr)) { + return parts[1].trim(); + } + } + return defaultKey; + } + static String getErrorMessage(String key, Object... pars) { Locale loc = Locale.getDefault(); ResourceBundle res = ResourceBundle.getBundle( diff --git a/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java b/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java index 51b12f4c7e..2985f61631 100644 --- a/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java +++ b/client-compiler/tests/src/com/vaadin/tools/CvalCheckerTest.java @@ -24,13 +24,17 @@ import static com.vaadin.tools.CvalChecker.GRACE_DAYS_MSECS; import static com.vaadin.tools.CvalChecker.cacheLicenseInfo; import static com.vaadin.tools.CvalChecker.deleteCache; import static com.vaadin.tools.CvalChecker.parseJson; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.io.PrintWriter; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -147,7 +151,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -158,7 +162,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -169,7 +173,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -180,7 +184,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -207,7 +211,7 @@ public class CvalCheckerTest { } catch (InvalidCvalException expected) { Assert.fail(); } catch (UnreachableCvalServerException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -221,7 +225,7 @@ public class CvalCheckerTest { } catch (InvalidCvalException expected) { Assert.fail(); } catch (UnreachableCvalServerException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertFalse(cacheExists(productNameCval)); @@ -234,7 +238,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); // Check that we use server customized message if it comes Assert.assertTrue(expected.getMessage().contains("Custom")); } @@ -255,7 +259,7 @@ public class CvalCheckerTest { productTitleCval); Assert.fail(); } catch (InvalidCvalException expected) { - Assert.assertEquals(productNameCval, expected.name); + assertEquals(productNameCval, expected.name); } Assert.assertTrue(cacheExists(productNameCval)); } @@ -339,4 +343,131 @@ public class CvalCheckerTest { static void restoreSystemOut() { System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); } + + @Test(expected = FileNotFoundException.class) + public void testReadKeyFromFile_NonexistingLicenseFile() throws Exception { + licenseChecker.readKeyFromFile(new URL("file:///foobar.baz"), 4); + } + + @Test + public void testReadKeyFromFile_LicenseFileEmpty() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + + assertNull(licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasSingleUnidentifiedKey() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasSingleIdentifiedKey() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4=this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasMultipleKeys() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4=this-is-a-license"); + out.println("5=this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_LicenseFileHasMultipleKeysWithWhitespace() + throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4 = this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_RequestedVersionMissing() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("4 = this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertNull(licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_FallbackToDefaultKey() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("this-is-a-license"); + out.println("5 = this-is-another-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } + + @Test + public void testReadKeyFromFile_FallbackToDefaultKeyReversed() throws Exception { + File tmpLicenseFile = File.createTempFile("license", "lic"); + PrintWriter out = new PrintWriter(tmpLicenseFile); + out.println("5 = this-is-another-license"); + out.println("this-is-a-license"); + out.close(); + + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 3)); + assertEquals("this-is-a-license", licenseChecker.readKeyFromFile(tmpLicenseFile.toURI() + .toURL(), 4)); + assertEquals("this-is-another-license", licenseChecker.readKeyFromFile( + tmpLicenseFile.toURI().toURL(), 5)); + + tmpLicenseFile.delete(); + } } diff --git a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml index 2719493853..461bd5ed1b 100755 --- a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml +++ b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml @@ -14,4 +14,8 @@ file. Speeds up compilation and does not make the Javascript significantly larger. --> <collapse-all-properties /> + + <!-- Workaround for http://dev.vaadin.com/ticket/14051 --> + <set-property name="compiler.useSymbolMaps" value="true" /> + </module> diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml index 711729f64f..aad0563975 100644 --- a/client/src/com/vaadin/Vaadin.gwt.xml +++ b/client/src/com/vaadin/Vaadin.gwt.xml @@ -68,7 +68,7 @@ <property-provider name="modernie"><![CDATA[ { var ua = $wnd.navigator.userAgent; - if (ua.indexOf('IE') == -1 && ua.indexOf('Trident') != -1) { return 'yes'; } + if (ua.indexOf('MSIE') == -1 && ua.indexOf('Trident') != -1) { return 'yes'; } return 'none'; } ]]></property-provider> diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 3ccbeba6f3..87c8ea465f 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -51,6 +51,7 @@ import com.vaadin.client.metadata.ConnectorBundleLoader; import com.vaadin.client.metadata.NoDataException; import com.vaadin.client.metadata.TypeData; import com.vaadin.client.ui.UnknownComponentConnector; +import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; @@ -84,7 +85,7 @@ public class ApplicationConfiguration implements EntryPoint { return null; } else { return value +""; - } + } }-*/; /** @@ -105,7 +106,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Boolean::valueOf(Z)(value); - } + } }-*/; /** @@ -126,7 +127,7 @@ public class ApplicationConfiguration implements EntryPoint { } else { // $entry not needed as function is not exported return @java.lang.Integer::valueOf(I)(value); - } + } }-*/; /** @@ -285,14 +286,16 @@ public class ApplicationConfiguration implements EntryPoint { return serviceUrl; } + /** + * @return the theme name used when initializing the application + * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} to get + * the theme currently in use + */ + @Deprecated public String getThemeName() { return getJsoConfiguration(id).getConfigString("theme"); } - public String getThemeUri() { - return getVaadinDirUrl() + "themes/" + getThemeName(); - } - /** * Gets the URL of the VAADIN directory on the server. * diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 6bbca98042..90aa0a14d6 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -66,7 +66,6 @@ import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; import com.vaadin.client.ResourceLoader.ResourceLoadEvent; import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.communication.HasJavaScriptConnectorHelper; @@ -111,14 +110,14 @@ import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; * This is the client side communication "engine", managing client-server * communication with its server side counterpart * com.vaadin.server.VaadinService. - * + * * Client-side connectors receive updates from the corresponding server-side * connector (typically component) as state updates or RPC calls. The connector * has the possibility to communicate back with its server side counter part * through RPC calls. - * + * * TODO document better - * + * * Entry point classes (widgetsets) define <code>onModuleLoad()</code>. */ public class ApplicationConnection implements HasHandlers { @@ -150,12 +149,12 @@ public class ApplicationConnection implements HasHandlers { * A string that, if found in a non-JSON response to a UIDL request, will * cause the browser to refresh the page. If followed by a colon, optional * whitespace, and a URI, causes the browser to synchronously load the URI. - * + * * <p> * This allows, for instance, a servlet filter to redirect the application * to a custom login page when the session expires. For example: * </p> - * + * * <pre> * if (sessionExpired) { * response.setHeader("Content-Type", "text/html"); @@ -168,7 +167,7 @@ public class ApplicationConnection implements HasHandlers { public static final String UIDL_REFRESH_TOKEN = "Vaadin-Refresh"; // will hold the CSRF token once received - private String csrfToken = "init"; + private String csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE; private final HashMap<String, String> resourcesMap = new HashMap<String, String>(); @@ -346,7 +345,7 @@ public class ApplicationConnection implements HasHandlers { /** * Event triggered when a XHR request has finished with the status code of * the response. - * + * * Useful for handlers observing network failures like online/off-line * monitors. */ @@ -402,12 +401,12 @@ public class ApplicationConnection implements HasHandlers { /** * Event triggered when a application is stopped by calling * {@link ApplicationConnection#setApplicationRunning(false)}. - * + * * To listen for the event add a {@link ApplicationStoppedHandler} by * invoking * {@link ApplicationConnection#addHandler(ApplicationConnection.ApplicationStoppedEvent.Type, ApplicationStoppedHandler)} * to the {@link ApplicationConnection} - * + * * @since 7.1.8 * @author Vaadin Ltd */ @@ -434,7 +433,7 @@ public class ApplicationConnection implements HasHandlers { /** * Called when a communication error has occurred. Returning * <code>true</code> from this method suppresses error handling. - * + * * @param details * A string describing the error. * @param statusCode @@ -449,7 +448,7 @@ public class ApplicationConnection implements HasHandlers { * A listener for listening to application stopped events. The listener can * be added to a {@link ApplicationConnection} by invoking * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)} - * + * * @since 7.1.8 * @author Vaadin Ltd */ @@ -459,7 +458,7 @@ public class ApplicationConnection implements HasHandlers { * Triggered when the {@link ApplicationConnection} marks a previously * running application as stopped by invoking * {@link ApplicationConnection#setApplicationRunning(false)} - * + * * @param event * the event triggered by the {@link ApplicationConnection} */ @@ -570,7 +569,7 @@ public class ApplicationConnection implements HasHandlers { * called once this application has started (first response received) or * failed to start. This ensures that the applications are started in order, * to avoid session-id problems. - * + * */ public void start() { String jsonText = configuration.getUIDL(); @@ -599,14 +598,23 @@ public class ApplicationConnection implements HasHandlers { } } + /** + * Checks if there is some work to be done on the client side + * + * @return true if the client has some work to be done, false otherwise + */ + private boolean isActive() { + return isWorkPending() || hasActiveRequest() + || isExecutingDeferredCommands(); + } + private native void initializeTestbenchHooks( ComponentLocator componentLocator, String TTAppId) /*-{ var ap = this; var client = {}; client.isActive = $entry(function() { - return ap.@com.vaadin.client.ApplicationConnection::hasActiveRequest()() - || ap.@com.vaadin.client.ApplicationConnection::isExecutingDeferredCommands()(); + return ap.@com.vaadin.client.ApplicationConnection::isActive()(); }); var vi = ap.@com.vaadin.client.ApplicationConnection::getVersionInfo()(); if (vi) { @@ -671,7 +679,7 @@ public class ApplicationConnection implements HasHandlers { * <li><code>vaadin.postRequestHooks</code> is a map of functions which gets * called after each XHR made by vaadin application. Note, that it is * attaching js functions responsibility to create the variable like this: - * + * * <code><pre> * if(!vaadin.postRequestHooks) {vaadin.postRequestHooks = new Object();} * postRequestHooks.myHook = function(appId) { @@ -682,7 +690,7 @@ public class ApplicationConnection implements HasHandlers { * </pre></code> First parameter passed to these functions is the identifier * of Vaadin application that made the request. * </ul> - * + * * TODO make this multi-app aware */ private native void initializeClientHooks() @@ -713,7 +721,7 @@ public class ApplicationConnection implements HasHandlers { /** * Runs possibly registered client side post request hooks. This is expected * to be run after each uidl request made by Vaadin application. - * + * * @param appId */ private static native void runPostRequestHooks(String appId) @@ -733,7 +741,7 @@ public class ApplicationConnection implements HasHandlers { /** * If on Liferay and logged in, ask the client side session management * JavaScript to extend the session duration. - * + * * Otherwise, Liferay client side JavaScript will explicitly expire the * session even though the server side considers the session to be active. * See ticket #8305 for more information. @@ -752,7 +760,7 @@ public class ApplicationConnection implements HasHandlers { /** * Indicates whether or not there are currently active UIDL requests. Used * internally to sequence requests properly, seldom needed in Widgets. - * + * * @return true if there are active requests */ public boolean hasActiveRequest() { @@ -772,7 +780,7 @@ public class ApplicationConnection implements HasHandlers { /** * Requests an analyze of layouts, to find inconsistencies. Exclusively used * for debugging during development. - * + * * @deprecated as of 7.1. Replaced by {@link UIConnector#analyzeLayouts()} */ @Deprecated @@ -784,7 +792,7 @@ public class ApplicationConnection implements HasHandlers { * Sends a request to the server to print details to console that will help * the developer to locate the corresponding server-side connector in the * source code. - * + * * @param serverConnector * @deprecated as of 7.1. Replaced by * {@link UIConnector#showServerDebugInfo(ServerConnector)} @@ -796,7 +804,7 @@ public class ApplicationConnection implements HasHandlers { /** * Makes an UIDL request to the server. - * + * * @param reqInvocations * Data containing RPC invocations and all related information. * @param extraParams @@ -810,8 +818,11 @@ public class ApplicationConnection implements HasHandlers { startRequest(); JSONObject payload = new JSONObject(); - payload.put(ApplicationConstants.CSRF_TOKEN, new JSONString( - getCsrfToken())); + if (!getCsrfToken().equals( + ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) { + payload.put(ApplicationConstants.CSRF_TOKEN, new JSONString( + getCsrfToken())); + } payload.put(ApplicationConstants.RPC_INVOCATIONS, reqInvocations); payload.put(ApplicationConstants.SERVER_SYNC_ID, new JSONNumber( lastSeenServerSyncId)); @@ -833,7 +844,7 @@ public class ApplicationConnection implements HasHandlers { /** * Sends an asynchronous or synchronous UIDL request to the server using the * given URI. - * + * * @param uri * The URI to use for the request. May includes GET parameters * @param payload @@ -971,7 +982,7 @@ public class ApplicationConnection implements HasHandlers { /** * Handles received UIDL JSON text, parsing it, and passing it on to the * appropriate handlers, while logging timing information. - * + * * @param jsonText * @param statusCode */ @@ -999,7 +1010,7 @@ public class ApplicationConnection implements HasHandlers { /** * Sends an asynchronous UIDL request to the server using the given URI. - * + * * @param uri * The URI to use for the request. May includes GET parameters * @param payload @@ -1134,7 +1145,7 @@ public class ApplicationConnection implements HasHandlers { /** * Checks whether or not the CSS is loaded. By default checks the size of * the loading indicator element. - * + * * @return */ protected boolean isCSSLoaded() { @@ -1144,12 +1155,12 @@ public class ApplicationConnection implements HasHandlers { /** * Shows the communication error notification. - * + * * @param details * Optional details for debugging. * @param statusCode * The status code returned for the request - * + * */ protected void showCommunicationError(String details, int statusCode) { VConsole.error("Communication error: " + details); @@ -1158,7 +1169,7 @@ public class ApplicationConnection implements HasHandlers { /** * Shows the authentication error notification. - * + * * @param details * Optional details for debugging. */ @@ -1169,7 +1180,7 @@ public class ApplicationConnection implements HasHandlers { /** * Shows the session expiration notification. - * + * * @param details * Optional details for debugging. */ @@ -1180,7 +1191,7 @@ public class ApplicationConnection implements HasHandlers { /** * Shows an error notification. - * + * * @param details * Optional details for debugging. * @param message @@ -1193,7 +1204,7 @@ public class ApplicationConnection implements HasHandlers { /** * Shows the error notification. - * + * * @param details * Optional details for debugging. */ @@ -1281,7 +1292,7 @@ public class ApplicationConnection implements HasHandlers { /** * This method is called after applying uidl change set to application. - * + * * It will clean current and queued variable change sets. And send next * change set if it exists. */ @@ -1300,7 +1311,7 @@ public class ApplicationConnection implements HasHandlers { /** * Cleans given queue of variable changes of such changes that came from * components that do not exist anymore. - * + * * @param variableBurst */ private void cleanVariableBurst( @@ -1318,6 +1329,30 @@ public class ApplicationConnection implements HasHandlers { } /** + * Checks if the client has running or scheduled commands + */ + private boolean isWorkPending() { + ConnectorMap connectorMap = getConnectorMap(); + JsArrayObject<ServerConnector> connectors = connectorMap + .getConnectorsAsJsArray(); + int size = connectors.size(); + for (int i = 0; i < size; i++) { + ServerConnector conn = connectors.get(i); + ComponentConnector compConn = null; + if (conn instanceof ComponentConnector) { + compConn = (ComponentConnector) conn; + Widget wgt = compConn.getWidget(); + if (wgt instanceof DeferredWorker) { + if (((DeferredWorker) wgt).isWorkPending()) { + return true; + } + } + } + } + return false; + } + + /** * Checks if deferred commands are (potentially) still being executed as a * result of an update from the server. Returns true if a deferred command * might still be executing, false otherwise. This will not work correctly @@ -1325,7 +1360,7 @@ public class ApplicationConnection implements HasHandlers { * <p> * Used by the native "client.isActive" function. * </p> - * + * * @return true if deferred commands are (potentially) being executed, false * otherwise */ @@ -1340,7 +1375,7 @@ public class ApplicationConnection implements HasHandlers { /** * Returns the loading indicator used by this ApplicationConnection - * + * * @return The loading indicator for this ApplicationConnection */ public VLoadingIndicator getLoadingIndicator() { @@ -1349,7 +1384,7 @@ public class ApplicationConnection implements HasHandlers { /** * Determines whether or not the loading indicator is showing. - * + * * @return true if the loading indicator is visible * @deprecated As of 7.1. Use {@link #getLoadingIndicator()} and * {@link VLoadingIndicator#isVisible()}.isVisible() instead. @@ -1383,7 +1418,7 @@ public class ApplicationConnection implements HasHandlers { * server is received. * <p> * The initial id when no request has yet been processed is -1. - * + * * @return and id identifying the response */ public int getLastResponseId() { @@ -1481,6 +1516,7 @@ public class ApplicationConnection implements HasHandlers { if (json.containsKey("typeMappings")) { configuration.addComponentMappings( json.getValueMap("typeMappings"), widgetSet); + } VConsole.log("Handling resource dependencies"); @@ -1715,6 +1751,7 @@ public class ApplicationConnection implements HasHandlers { for (int i = 0; i < needsUpdateLength; i++) { String childId = dump.get(i); ServerConnector child = connectorMap.getConnector(childId); + if (child instanceof ComponentConnector && ((ComponentConnector) child) .delegateCaptionHandling()) { @@ -1806,13 +1843,13 @@ public class ApplicationConnection implements HasHandlers { /** * Sends the state change events created while updating the state * information. - * + * * This must be called after hierarchy change listeners have been * called. At least caption updates for the parent are strange if * fired from state change listeners and thus calls the parent * BEFORE the parent is aware of the child (through a * ConnectorHierarchyChangedEvent) - * + * * @param pendingStateChangeEvents * The events to send */ @@ -2127,7 +2164,7 @@ public class ApplicationConnection implements HasHandlers { * Updates the connector hierarchy and returns a list of events that * should be fired after update of the hierarchy and the state is * done. - * + * * @param json * The JSON containing the hierarchy information * @return A collection of events that should be fired when update @@ -2524,9 +2561,9 @@ public class ApplicationConnection implements HasHandlers { /** * Adds an explicit RPC method invocation to the send queue. - * + * * @since 7.0 - * + * * @param invocation * RPC method invocation * @param delayed @@ -2566,7 +2603,7 @@ public class ApplicationConnection implements HasHandlers { /** * Removes any pending invocation of the given method from the queue - * + * * @param invocation * The invocation to remove */ @@ -2584,12 +2621,12 @@ public class ApplicationConnection implements HasHandlers { /** * This method sends currently queued variable changes to server. It is * called when immediate variable update must happen. - * + * * To ensure correct order for variable changes (due servers multithreading * or network), we always wait for active request to be handler before * sending a new one. If there is an active request, we will put varible * "burst" to queue that will be purged after current request is handled. - * + * */ public void sendPendingVariableChanges() { if (!deferedSendPending) { @@ -2630,11 +2667,11 @@ public class ApplicationConnection implements HasHandlers { /** * Build the variable burst and send it to server. - * + * * When sync is forced, we also force sending of all pending variable-bursts * at the same time. This is ok as we can assume that DOM will never be * updated after this. - * + * * @param pendingInvocations * List of RPC method invocations to send */ @@ -2721,7 +2758,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2743,7 +2780,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2766,7 +2803,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2789,7 +2826,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2812,7 +2849,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2835,7 +2872,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2858,7 +2895,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2881,7 +2918,7 @@ public class ApplicationConnection implements HasHandlers { * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. * </p> - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2898,13 +2935,13 @@ public class ApplicationConnection implements HasHandlers { /** * Sends a new value for the given paintables given variable to the server. - * + * * The update is actually queued to be sent at a suitable time. If immediate * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. - * + * * A null array is sent as an empty array. - * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2921,14 +2958,14 @@ public class ApplicationConnection implements HasHandlers { /** * Sends a new value for the given paintables given variable to the server. - * + * * The update is actually queued to be sent at a suitable time. If immediate * is true, the update is sent as soon as possible. If immediate is false, * the update will be sent along with the next immediate update. </p> - * + * * A null array is sent as an empty array. - * - * + * + * * @param paintableId * the id of the paintable that owns the variable * @param variableName @@ -2945,7 +2982,7 @@ public class ApplicationConnection implements HasHandlers { /** * Does absolutely nothing. Replaced by {@link LayoutManager}. - * + * * @param container * @deprecated As of 7.0, serves no purpose */ @@ -2967,7 +3004,7 @@ public class ApplicationConnection implements HasHandlers { /** * Returns false - * + * * @param paintable * @return false, always * @deprecated As of 7.0, serves no purpose @@ -2979,7 +3016,7 @@ public class ApplicationConnection implements HasHandlers { /** * Returns false - * + * * @param paintable * @return false, always * @deprecated As of 7.0, serves no purpose @@ -3000,16 +3037,16 @@ public class ApplicationConnection implements HasHandlers { /** * Get either an existing ComponentConnector or create a new * ComponentConnector with the given type and id. - * + * * If a ComponentConnector with the given id already exists, returns it. * Otherwise creates and registers a new ComponentConnector of the given * type. - * + * * @param connectorId * Id of the paintable * @param connectorType * Type of the connector, as passed from the server side - * + * * @return Either an existing ComponentConnector or a new ComponentConnector * of the given type */ @@ -3022,15 +3059,15 @@ public class ApplicationConnection implements HasHandlers { /** * Creates a new ServerConnector with the given type and id. - * + * * Creates and registers a new ServerConnector of the given type. Should * never be called with the connector id of an existing connector. - * + * * @param connectorId * Id of the new connector * @param connectorType * Type of the connector, as passed from the server side - * + * * @return A new ServerConnector of the given type */ private ServerConnector createAndRegisterConnector(String connectorId, @@ -3050,7 +3087,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets a recource that has been pre-loaded via UIDL, such as custom * layouts. - * + * * @param name * identifier of the resource to get * @return the resource @@ -3061,7 +3098,7 @@ public class ApplicationConnection implements HasHandlers { /** * Singleton method to get instance of app's context menu. - * + * * @return VContextMenu object */ public VContextMenu getContextMenu() { @@ -3076,7 +3113,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets an {@link Icon} instance corresponding to a URI. - * + * * @since 7.2 * @param uri * @return Icon object @@ -3098,7 +3135,7 @@ public class ApplicationConnection implements HasHandlers { * Translates custom protocols in UIDL URI's to be recognizable by browser. * All uri's from UIDL should be routed via this method before giving them * to browser due URI's in UIDL may contain custom protocols like theme://. - * + * * @param uidlUri * Vaadin URI from uidl * @return translated URI ready for browser @@ -3108,7 +3145,7 @@ public class ApplicationConnection implements HasHandlers { return null; } if (uidlUri.startsWith("theme://")) { - final String themeUri = configuration.getThemeUri(); + final String themeUri = getThemeUri(); if (themeUri == null) { VConsole.error("Theme not set: ThemeResource will not be found. (" + uidlUri + ")"); @@ -3170,17 +3207,18 @@ public class ApplicationConnection implements HasHandlers { /** * Gets the URI for the current theme. Can be used to reference theme * resources. - * + * * @return URI to the current theme */ public String getThemeUri() { - return configuration.getThemeUri(); + return configuration.getVaadinDirUrl() + "themes/" + + getUIConnector().getActiveTheme(); } /** * Listens for Notification hide event, and redirects. Used for system * messages, such as session expired. - * + * */ private class NotificationRedirect implements VNotification.EventListener { String url; @@ -3209,7 +3247,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets the token (aka double submit cookie) that the server uses to protect * against Cross Site Request Forgery attacks. - * + * * @return the CSRF token string */ public String getCsrfToken() { @@ -3219,7 +3257,7 @@ public class ApplicationConnection implements HasHandlers { /** * Use to notify that the given component's caption has changed; layouts may * have to be recalculated. - * + * * @param component * the Paintable whose caption has changed * @deprecated As of 7.0.2, has not had any effect for a long time @@ -3231,7 +3269,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets the main view - * + * * @return the main view */ public UIConnector getUIConnector() { @@ -3240,7 +3278,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets the {@link ApplicationConfiguration} for the current application. - * + * * @see ApplicationConfiguration * @return the configuration for this application */ @@ -3253,7 +3291,7 @@ public class ApplicationConnection implements HasHandlers { * list of events which has server side listeners is updated automatically * before the component is updated so the value is correct if called from * updatedFromUIDL. - * + * * @param paintable * The connector to register event listeners for * @param eventIdentifier @@ -3273,7 +3311,7 @@ public class ApplicationConnection implements HasHandlers { /** * Adds the get parameters to the uri and returns the new uri that contains * the parameters. - * + * * @param uri * The uri to which the parameters should be added. * @param extraParams @@ -3326,7 +3364,7 @@ public class ApplicationConnection implements HasHandlers { /** * Get VTooltip instance related to application connection - * + * * @return VTooltip instance */ public VTooltip getVTooltip() { @@ -3338,7 +3376,7 @@ public class ApplicationConnection implements HasHandlers { * this method is now handled by the state change event handler in * AbstractComponentConnector. The only function this method has is to * return true if the UIDL is a "cached" update. - * + * * @param component * @param uidl * @param manageCaption @@ -3389,7 +3427,7 @@ public class ApplicationConnection implements HasHandlers { * Schedules a heartbeat request to occur after the configured heartbeat * interval elapses if the interval is a positive number. Otherwise, does * nothing. - * + * * @deprecated as of 7.2, use {@link Heartbeat#schedule()} instead */ @Deprecated @@ -3403,7 +3441,7 @@ public class ApplicationConnection implements HasHandlers { * Heartbeat requests are used to inform the server that the client-side is * still alive. If the client page is closed or the connection lost, the * server will eventually close the inactive UI. - * + * * @deprecated as of 7.2, use {@link Heartbeat#send()} instead */ @Deprecated @@ -3427,7 +3465,7 @@ public class ApplicationConnection implements HasHandlers { /** * This method can be used to postpone rendering of a response for a short * period of time (e.g. to avoid the rendering process during animation). - * + * * @param lock */ public void suspendReponseHandling(Object lock) { @@ -3436,7 +3474,7 @@ public class ApplicationConnection implements HasHandlers { /** * Resumes the rendering process once all locks have been removed. - * + * * @param lock */ public void resumeResponseHandling(Object lock) { @@ -3481,7 +3519,7 @@ public class ApplicationConnection implements HasHandlers { /** * Sets the delegate that is called whenever a communication error occurrs. - * + * * @param delegate * the delegate. */ @@ -3524,7 +3562,7 @@ public class ApplicationConnection implements HasHandlers { /** * Gets the active connector for focused element in browser. - * + * * @return Connector for focused element or null. */ private ComponentConnector getActiveConnector() { @@ -3538,7 +3576,7 @@ public class ApplicationConnection implements HasHandlers { /** * Sets the status for the push connection. - * + * * @param enabled * <code>true</code> to enable the push connection; * <code>false</code> to disable the push connection. @@ -3588,7 +3626,7 @@ public class ApplicationConnection implements HasHandlers { /** * Returns a human readable string representation of the method used to * communicate with the server. - * + * * @since 7.1 * @return A string representation of the current transport type */ diff --git a/client/src/com/vaadin/client/DeferredWorker.java b/client/src/com/vaadin/client/DeferredWorker.java new file mode 100644 index 0000000000..53f7c79fe6 --- /dev/null +++ b/client/src/com/vaadin/client/DeferredWorker.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.client; + +/** + * Give widgets the possibility to indicate to the framework that there is work + * scheduled to be executed in the near future and that the framework should + * wait for this work to complete before assuming the UI has reached a steady + * state. + */ +public interface DeferredWorker { + /** + * @returns true, if there are operations pending which must be executed + * before reaching a steady state + */ + public boolean isWorkPending(); +} diff --git a/client/src/com/vaadin/client/ResourceLoader.java b/client/src/com/vaadin/client/ResourceLoader.java index 68a16e8162..ceede263fc 100644 --- a/client/src/com/vaadin/client/ResourceLoader.java +++ b/client/src/com/vaadin/client/ResourceLoader.java @@ -375,7 +375,20 @@ public class ResourceLoader { } } - private native void addOnloadHandler(Element element, + /** + * Adds an onload listener to the given element, which should be a link or a + * script tag. The listener is called whenever loading is complete or an + * error occurred. + * + * @since 7.3 + * @param element + * the element to attach a listener to + * @param listener + * the listener to call + * @param event + * the event passed to the listener + */ + public static native void addOnloadHandler(Element element, ResourceLoadListener listener, ResourceLoadEvent event) /*-{ element.onload = $entry(function() { @@ -390,11 +403,11 @@ public class ResourceLoader { element.onreadystatechange = null; listener.@com.vaadin.client.ResourceLoader.ResourceLoadListener::onError(Lcom/vaadin/client/ResourceLoader$ResourceLoadEvent;)(event); }); - element.onreadystatechange = function() { + element.onreadystatechange = function() { if ("loaded" === element.readyState || "complete" === element.readyState ) { element.onload(arguments[0]); } - }; + }; }-*/; /** @@ -520,12 +533,12 @@ public class ResourceLoader { if (rules === undefined) { rules = sheet.rules; } - + if (rules === null) { // Style sheet loaded, but can't access length because of XSS -> assume there's something there return 1; } - + // Return length so we can distinguish 0 (probably 404 error) from normal case. return rules.length; } catch (err) { diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index 507a5c2c2d..e37b044826 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -16,11 +16,14 @@ package com.vaadin.client; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -36,6 +39,8 @@ import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.KeyEvent; +import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -56,9 +61,9 @@ public class Util { /** * Helper method for debugging purposes. - * + * * Stops execution on firefox browsers on a breakpoint. - * + * */ public static native void browserDebugger() /*-{ @@ -86,10 +91,10 @@ public class Util { /** * * Returns the topmost element of from given coordinates. - * + * * TODO fix crossplat issues clientX vs pageX. See quircksmode. Not critical * for vaadin as we scroll div istead of page. - * + * * @param x * @param y * @return the element at given coordinates @@ -98,7 +103,7 @@ public class Util { int clientX, int clientY) /*-{ var el = $wnd.document.elementFromPoint(clientX, clientY); - // Call elementFromPoint two times to make sure IE8 also returns something sensible if the application is running in an iframe + // Call elementFromPoint two times to make sure IE8 also returns something sensible if the application is running in an iframe el = $wnd.document.elementFromPoint(clientX, clientY); if(el != null && el.nodeType == 3) { el = el.parentNode; @@ -110,18 +115,18 @@ public class Util { * This helper method can be called if components size have been changed * outside rendering phase. It notifies components parent about the size * change so it can react. - * + * * When using this method, developer should consider if size changes could * be notified lazily. If lazy flag is true, method will save widget and * wait for a moment until it notifies parents in chunks. This may vastly * optimize layout in various situation. Example: if component have a lot of * images their onload events may fire "layout phase" many times in a short * period. - * + * * @param widget * @param lazy * run componentSizeUpdated lazyly - * + * * @deprecated As of 7.0, use * {@link LayoutManager#setNeedsMeasure(ComponentConnector)} * instead @@ -171,7 +176,7 @@ public class Util { /** * Converts html entities to text. - * + * * @param html * @return escaped string presentation of given html */ @@ -189,7 +194,7 @@ public class Util { /** * Escapes the string so it is safe to write inside an HTML attribute. - * + * * @param attribute * The string to escape * @return An escaped version of <literal>attribute</literal>. @@ -208,9 +213,9 @@ public class Util { /** * Clones given element as in JavaScript. - * + * * Deprecate this if there appears similar method into GWT someday. - * + * * @param element * @param deep * clone child tree also @@ -469,10 +474,28 @@ public class Util { } /** - * Run workaround for webkits overflow auto issue. + * Defers the execution of {@link #runWebkitOverflowAutoFix(Element)} * + * @since + * @param elem + * with overflow auto + */ + public static void runWebkitOverflowAutoFixDeferred(final Element elem) { + Scheduler.get().scheduleDeferred(new Command() { + + @Override + public void execute() { + Util.runWebkitOverflowAutoFix(elem); + } + }); + + } + + /** + * Run workaround for webkits overflow auto issue. + * * See: our bug #2138 and https://bugs.webkit.org/show_bug.cgi?id=21462 - * + * * @param elem * with overflow auto */ @@ -543,7 +566,7 @@ public class Util { * dimension is not specified as relative it will return -1. If the shared * state does not contain width or height specifications this will return * null. - * + * * @param state * @return */ @@ -576,7 +599,7 @@ public class Util { * Checks if a and b are equals using {@link #equals(Object)}. Handles null * values as well. Does not ensure that objects are of the same type. * Assumes that the first object's equals method handle equals properly. - * + * * @param a * The first value to compare * @param b @@ -597,7 +620,7 @@ public class Util { /** * Gets the border-box width for the given element, i.e. element width + * border + padding. Always rounds up to nearest integer. - * + * * @param element * The element to check * @return The border-box width for the element @@ -622,7 +645,7 @@ public class Util { /** * Gets the border-box height for the given element, i.e. element height + * border + padding. Always rounds up to nearest integer. - * + * * @param element * The element to check * @return The border-box height for the element @@ -669,7 +692,7 @@ public class Util { var borderBottomPx = cs.borderBottom; var paddingTopPx = cs.paddingTop; var paddingBottomPx = cs.paddingBottom; - + var height = heightPx.substring(0,heightPx.length-2); var border = borderTopPx.substring(0,borderTopPx.length-2)+borderBottomPx.substring(0,borderBottomPx.length-2); var padding = paddingTopPx.substring(0,paddingTopPx.length-2)+paddingBottomPx.substring(0,paddingBottomPx.length-2); @@ -689,7 +712,7 @@ public class Util { var borderRightPx = cs.borderRight; var paddingLeftPx = cs.paddingLeft; var paddingRightPx = cs.paddingRight; - + var width = widthPx.substring(0,widthPx.length-2); var border = borderLeftPx.substring(0,borderLeftPx.length-2)+borderRightPx.substring(0,borderRightPx.length-2); var padding = paddingLeftPx.substring(0,paddingLeftPx.length-2)+paddingRightPx.substring(0,paddingRightPx.length-2); @@ -719,7 +742,7 @@ public class Util { /** * Detects what is currently the overflow style attribute in given element. - * + * * @param pe * the element to detect * @return true if auto or scroll @@ -741,7 +764,7 @@ public class Util { * A simple helper method to detect "computed style" (aka style sheets + * element styles). Values returned differ a lot depending on browsers. * Always be very careful when using this. - * + * * @param el * the element from which the style property is detected * @param p @@ -752,7 +775,7 @@ public class Util { com.google.gwt.dom.client.Element el, String p) /*-{ try { - + if (el.currentStyle) { // IE return el.currentStyle[p]; @@ -776,9 +799,9 @@ public class Util { * also returned if "element" is part of its caption. If * <literal>element</literal> is not part of any child component, null is * returned. - * + * * This method returns the deepest nested VPaintableWidget. - * + * * @param client * A reference to ApplicationConnection * @param parent @@ -836,7 +859,7 @@ public class Util { /** * Will (attempt) to focus the given DOM Element. - * + * * @param el * the element to focus */ @@ -852,7 +875,7 @@ public class Util { /** * Helper method to find the nearest parent paintable instance by traversing * the DOM upwards from given element. - * + * * @param element * the element to start from */ @@ -870,7 +893,7 @@ public class Util { /** * Helper method to find first instance of given Widget type found by * traversing DOM upwards from given element. - * + * * @param element * the element where to start seeking of Widget * @param class1 @@ -907,7 +930,7 @@ public class Util { /** * Force webkit to redraw an element - * + * * @param element * The element that should be redrawn */ @@ -925,12 +948,27 @@ public class Util { * Performs a hack to trigger a re-layout in the IE8. This is usually * necessary in cases where IE8 "forgets" to update child elements when they * resize. - * + * * @param e * The element to perform the hack on */ public static final void forceIE8Redraw(Element e) { if (BrowserInfo.get().isIE8()) { + forceIERedraw(e); + } + } + + /** + * Performs a hack to trigger a re-layout in the IE browser. This is usually + * necessary in cases where IE "forgets" to update child elements when they + * resize. + * + * @since + * @param e + * The element to perform the hack on + */ + public static void forceIERedraw(Element e) { + if (BrowserInfo.get().isIE()) { setStyleTemporarily(e, "zoom", "1"); } } @@ -938,9 +976,9 @@ public class Util { /** * Detaches and re-attaches the element from its parent. The element is * reattached at the same position in the DOM as it was before. - * + * * Does nothing if the element is not attached to the DOM. - * + * * @param element * The element to detach and re-attach */ @@ -975,7 +1013,7 @@ public class Util { /** * Returns the index of the childElement within its parent. - * + * * @param subElement * @return */ @@ -1051,7 +1089,7 @@ public class Util { * Temporarily sets the {@code styleProperty} to {@code tempValue} and then * resets it to its current value. Used mainly to work around rendering * issues in IE (and possibly in other browsers) - * + * * @param element * The target element * @param styleProperty @@ -1074,7 +1112,7 @@ public class Util { * A helper method to return the client position from an event. Returns * position from either first changed touch (if touch event) or from the * event itself. - * + * * @param event * @return */ @@ -1090,7 +1128,7 @@ public class Util { * Find the element corresponding to the coordinates in the passed mouse * event. Please note that this is not always the same as the target of the * event e.g. if event capture is used. - * + * * @param event * the mouse event to get coordinates from * @return the element at the coordinates of the event @@ -1107,7 +1145,7 @@ public class Util { * A helper method to return the client position from an event. Returns * position from either first changed touch (if touch event) or from the * event itself. - * + * * @param event * @return */ @@ -1120,7 +1158,7 @@ public class Util { } /** - * + * * @see #getTouchOrMouseClientY(Event) * @param currentGwtEvent * @return @@ -1131,7 +1169,7 @@ public class Util { /** * @see #getTouchOrMouseClientX(Event) - * + * * @param event * @return */ @@ -1200,7 +1238,7 @@ public class Util { /** * Gets the currently focused element. - * + * * @return The active element or null if no active element could be found. */ public native static com.google.gwt.user.client.Element getFocusedElement() @@ -1208,13 +1246,13 @@ public class Util { if ($wnd.document.activeElement) { return $wnd.document.activeElement; } - + return null; }-*/; /** * Gets the currently focused element for Internet Explorer. - * + * * @return The currently focused element * @deprecated Use #getFocusedElement instead */ @@ -1228,7 +1266,7 @@ public class Util { * this method checks that this widget nor any of its parents is hidden. Can * be e.g used to check whether component should react to some events or * not. - * + * * @param widget * @return true if attached and displayed */ @@ -1261,7 +1299,7 @@ public class Util { /** * Scrolls an element into view vertically only. Modified version of * Element.scrollIntoView. - * + * * @param elem * The element to scroll into view */ @@ -1269,11 +1307,11 @@ public class Util { /*-{ var top = elem.offsetTop; var height = elem.offsetHeight; - + if (elem.parentNode != elem.offsetParent) { top -= elem.parentNode.offsetTop; } - + var cur = elem.parentNode; while (cur && (cur.nodeType == 1)) { if (top < cur.scrollTop) { @@ -1282,12 +1320,12 @@ public class Util { if (top + height > cur.scrollTop + cur.clientHeight) { cur.scrollTop = (top + height) - cur.clientHeight; } - + var offsetTop = cur.offsetTop; if (cur.parentNode != cur.offsetParent) { offsetTop -= cur.parentNode.offsetTop; } - + top += offsetTop - cur.scrollTop; cur = cur.parentNode; } @@ -1296,7 +1334,7 @@ public class Util { /** * Checks if the given event is either a touch event or caused by the left * mouse button - * + * * @param event * @return true if the event is a touch event or caused by the left mouse * button, false otherwise @@ -1308,7 +1346,7 @@ public class Util { /** * Performs a shallow comparison of the collections. - * + * * @param collection1 * The first collection * @param collection2 @@ -1354,7 +1392,7 @@ public class Util { /** * Resolve a relative URL to an absolute URL based on the current document's * location. - * + * * @param url * a string with the relative URL to resolve * @return the corresponding absolute URL as a string @@ -1381,4 +1419,193 @@ public class Util { } } + /** + * Sets the selection range of an input element. + * + * We need this JSNI function to set selection range so that we can use the + * optional direction attribute to set the anchor to the end and the focus + * to the start. This makes Firefox work the same way as other browsers + * (#13477) + * + * @param elem + * the html input element. + * @param pos + * the index of the first selected character. + * @param length + * the selection length. + * @param direction + * a string indicating the direction in which the selection was + * performed. This may be "forward" or "backward", or "none" if + * the direction is unknown or irrelevant. + * + * @since + */ + public native static void setSelectionRange(Element elem, int pos, + int length, String direction) + /*-{ + try { + elem.setSelectionRange(pos, pos + length, direction); + } catch (e) { + // Firefox throws exception if TextBox is not visible, even if attached + } + }-*/; + + /** + * Wrap a css size value and its unit and translate back and forth to the + * string representation.<br/> + * Eg. 50%, 123px, ... + * + * @since + * @author Vaadin Ltd + */ + @SuppressWarnings("serial") + public static class CssSize implements Serializable { + + /* + * Map the size units with their type. + */ + private static Map<String, Unit> type2Unit = new HashMap<String, Style.Unit>(); + static { + for (Unit unit : Unit.values()) { + type2Unit.put(unit.getType(), unit); + } + } + + /** + * Gets the unit value by its type. + * + * @since + * @param type + * the type of the unit as found in the style. + * @return the unit value. + */ + public static Unit unitByType(String type) { + return type2Unit.get(type); + } + + /* + * Regex to parse the size. + */ + private static final RegExp sizePattern = RegExp + .compile(SharedUtil.SIZE_PATTERN); + + /** + * Parse the size from string format to {@link CssSize}. + * + * @param s + * the size as string. + * @return a {@link CssSize} object. + */ + public static CssSize fromString(String s) { + if (s == null) { + return null; + } + + s = s.trim(); + if ("".equals(s)) { + return null; + } + + float size = 0; + Unit unit = null; + + MatchResult matcher = sizePattern.exec(s); + if (matcher.getGroupCount() > 1) { + + size = Float.parseFloat(matcher.getGroup(1)); + if (size < 0) { + size = -1; + unit = Unit.PX; + + } else { + String symbol = matcher.getGroup(2); + unit = unitByType(symbol); + } + } else { + throw new IllegalArgumentException("Invalid size argument: \"" + + s + "\" (should match " + sizePattern.getSource() + + ")"); + } + return new CssSize(size, unit); + } + + /** + * Creates a {@link CssSize} using a value and its measurement unit. + * + * @since + * @param value + * the value. + * @param unit + * the unit. + * @return the {@link CssSize} object. + */ + public static CssSize fromValueUnit(float value, Unit unit) { + return new CssSize(value, unit); + } + + /* + * The value. + */ + private final float value; + + /* + * The measure unit. + */ + private final Unit unit; + + private CssSize(float value, Unit unit) { + this.value = value; + this.unit = unit; + } + + /** + * Gets the value for this css size. + * + * @return the value. + */ + public float getValue() { + return value; + } + + /** + * Gets the measurement unit for this css size. + * + * @return the unit. + */ + public Unit getUnit() { + return unit; + } + + @Override + public String toString() { + return value + unit.getType(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CssSize) { + CssSize size = (CssSize) obj; + return size.value == value && size.unit == unit; + } + + return false; + } + + /** + * Check whether the two sizes are equals. + * + * @since + * @param cssSize1 + * the first size to compare. + * @param cssSize2 + * the other size to compare with the first one. + * @return true if the two sizes are equals, otherwise false. + */ + public static boolean equals(String cssSize1, String cssSize2) { + return CssSize.fromString(cssSize1).equals( + CssSize.fromString(cssSize2)); + } + + } + } diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index 48e17cde05..5073e0ce5d 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -37,7 +37,7 @@ import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; /** * The default {@link PushConnection} implementation that uses Atmosphere for * handling the communication channel. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -171,8 +171,12 @@ public class AtmospherePushConnection implements PushConnection { + ApplicationConstants.PUSH_PATH + '/'); String extraParams = UIConstants.UI_ID_PARAMETER + "=" + connection.getConfiguration().getUIId(); - extraParams += "&" + ApplicationConstants.CSRF_TOKEN_PARAMETER + "=" - + connection.getCsrfToken(); + + if (!connection.getCsrfToken().equals( + ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE)) { + extraParams += "&" + ApplicationConstants.CSRF_TOKEN_PARAMETER + + "=" + connection.getCsrfToken(); + } // uri is needed to identify the right connection when closing uri = ApplicationConnection.addGetParameters(baseUrl, extraParams); @@ -239,9 +243,9 @@ public class AtmospherePushConnection implements PushConnection { /** * Called whenever a server push connection is established (or * re-established). - * + * * @param response - * + * * @since 7.2 */ protected void onConnect(AtmosphereResponse response) { @@ -330,7 +334,7 @@ public class AtmospherePushConnection implements PushConnection { /** * Called if the push connection fails. Atmosphere will automatically retry * the connection until successful. - * + * */ protected void onError(AtmosphereResponse response) { state = State.DISCONNECTED; @@ -448,7 +452,7 @@ public class AtmospherePushConnection implements PushConnection { contentType: 'application/json; charset=UTF-8', reconnectInterval: 5000, timeout: -1, - maxReconnectOnClose: 10000000, + maxReconnectOnClose: 10000000, trackMessageLength: true, enableProtocol: true, messageDelimiter: String.fromCharCode(@com.vaadin.shared.communication.PushConstants::MESSAGE_DELIMITER) @@ -501,7 +505,7 @@ public class AtmospherePushConnection implements PushConnection { private static native boolean isAtmosphereLoaded() /*-{ - return $wnd.jQueryVaadin != undefined; + return $wnd.jQueryVaadin != undefined; }-*/; private void runWhenAtmosphereLoaded(final Command command) { diff --git a/client/src/com/vaadin/client/communication/Heartbeat.java b/client/src/com/vaadin/client/communication/Heartbeat.java index 1ff0825f0e..b9493d4520 100644 --- a/client/src/com/vaadin/client/communication/Heartbeat.java +++ b/client/src/com/vaadin/client/communication/Heartbeat.java @@ -124,7 +124,9 @@ public class Heartbeat { @Override public void onError(Request request, Throwable exception) { - getLogger().severe("Exception sending heartbeat: " + exception.getMessage()); + getLogger().severe( + "Exception sending heartbeat: " + + exception.getMessage()); // Notify network observers about response status connection.fireEvent(new ConnectionStatusEvent(0)); // Don't break the loop diff --git a/client/src/com/vaadin/client/communication/TranslatedURLReference.java b/client/src/com/vaadin/client/communication/TranslatedURLReference.java new file mode 100644 index 0000000000..b99f4c6e32 --- /dev/null +++ b/client/src/com/vaadin/client/communication/TranslatedURLReference.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.client.communication; + +import com.vaadin.client.ApplicationConnection; +import com.vaadin.shared.communication.URLReference; + +/** + * A URLReference implementation which does late URL translation to be able to + * re-translate URLs if e.g. the theme changes + * + * @since 7.3 + * @author Vaadin Ltd + */ +public class TranslatedURLReference extends URLReference { + + private ApplicationConnection connection; + + /** + * @param connection + * the connection to set + */ + public void setConnection(ApplicationConnection connection) { + this.connection = connection; + } + + @Override + public String getURL() { + return connection.translateVaadinUri(super.getURL()); + } + +} diff --git a/client/src/com/vaadin/client/communication/URLReference_Serializer.java b/client/src/com/vaadin/client/communication/URLReference_Serializer.java index 586dd626f0..4ecdc606d2 100644 --- a/client/src/com/vaadin/client/communication/URLReference_Serializer.java +++ b/client/src/com/vaadin/client/communication/URLReference_Serializer.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -30,14 +30,16 @@ public class URLReference_Serializer implements JSONSerializer<URLReference> { @Override public URLReference deserialize(Type type, JSONValue jsonValue, ApplicationConnection connection) { - URLReference reference = GWT.create(URLReference.class); + TranslatedURLReference reference = GWT + .create(TranslatedURLReference.class); + reference.setConnection(connection); JSONObject json = (JSONObject) jsonValue; if (json.containsKey(URL_FIELD)) { JSONValue jsonURL = json.get(URL_FIELD); String URL = (String) JsonDecoder.decodeValue( new Type(String.class.getName(), null), jsonURL, null, connection); - reference.setURL(connection.translateVaadinUri(URL)); + reference.setURL(URL); } return reference; } diff --git a/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java index 6eb732bf46..15a156a815 100644 --- a/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java +++ b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java @@ -87,8 +87,7 @@ public interface LocatorStrategy { * @return The DOM element identified by {@code path} or null if the element * could not be located. */ - Element getElementByPathStartingAt(String path, - Element root); + Element getElementByPathStartingAt(String path, Element root); /** * Locates all elements that match a String locator (path) which identifies @@ -119,6 +118,5 @@ public interface LocatorStrategy { * found. */ - List<Element> getElementsByPathStartingAt( - String path, Element root); + List<Element> getElementsByPathStartingAt(String path, Element root); } diff --git a/client/src/com/vaadin/client/debug/internal/HierarchySection.java b/client/src/com/vaadin/client/debug/internal/HierarchySection.java index 1eacf286e8..404ac430df 100644 --- a/client/src/com/vaadin/client/debug/internal/HierarchySection.java +++ b/client/src/com/vaadin/client/debug/internal/HierarchySection.java @@ -108,16 +108,14 @@ public class HierarchySection implements Section { hierarchyPanel.addListener(new SelectConnectorListener() { @Override - public void select(ServerConnector connector, - Element element) { + public void select(ServerConnector connector, Element element) { printState(connector, true); } }); analyzeLayoutsPanel.addListener(new SelectConnectorListener() { @Override - public void select(ServerConnector connector, - Element element) { + public void select(ServerConnector connector, Element element) { printState(connector, true); } }); diff --git a/client/src/com/vaadin/client/debug/internal/InfoSection.java b/client/src/com/vaadin/client/debug/internal/InfoSection.java index 23b77a94db..a7a84f5f8f 100644 --- a/client/src/com/vaadin/client/debug/internal/InfoSection.java +++ b/client/src/com/vaadin/client/debug/internal/InfoSection.java @@ -163,7 +163,7 @@ public class InfoSection implements Section { addVersionInfo(configuration); addRow("Widget set", GWT.getModuleName()); - addRow("Theme", connection.getConfiguration().getThemeName()); + addRow("Theme", connection.getUIConnector().getActiveTheme()); String communicationMethodInfo = connection .getCommunicationMethodName(); diff --git a/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java index c3652c78e8..46c8070b30 100644 --- a/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java +++ b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java @@ -33,6 +33,5 @@ public interface SelectConnectorListener { * @param element * selected element of the connector or null if unknown */ - public void select(ServerConnector connector, - Element element); + public void select(ServerConnector connector, Element element); } diff --git a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java index 62913400db..8e349bac7b 100644 --- a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java +++ b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java @@ -302,11 +302,11 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements }-*/; - private String currentWidthRanges; - private String currentHeightRanges; + private String currentWidthRanges = ""; + private String currentHeightRanges = ""; @Override - public void onElementResize(ElementResizeEvent event) { + public void onElementResize(final ElementResizeEvent event) { int width = event.getLayoutManager().getOuterWidth(event.getElement()); int height = event.getLayoutManager() .getOuterHeight(event.getElement()); @@ -315,6 +315,9 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements .getElement(); boolean forceRedraw = false; + String oldWidthRanges = currentWidthRanges; + String oldHeightRanges = currentHeightRanges; + // Loop through breakpoints and see which one applies to this width currentWidthRanges = resolveBreakpoint("width", width, event.getElement()); @@ -342,6 +345,14 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements if (forceRedraw) { forceRedrawIfIE8(element); } + + // If a new breakpoint is triggered, ensure all sizes are updated in + // case some new styles are applied + if (!currentWidthRanges.equals(oldWidthRanges) + || !currentHeightRanges.equals(oldHeightRanges)) { + event.getLayoutManager().setNeedsMeasureRecursively( + ResponsiveConnector.this.target); + } } /** diff --git a/client/src/com/vaadin/client/ui/AbstractConnector.java b/client/src/com/vaadin/client/ui/AbstractConnector.java index a2e0d9cd54..e93ea0f507 100644 --- a/client/src/com/vaadin/client/ui/AbstractConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractConnector.java @@ -28,6 +28,7 @@ import com.google.gwt.event.shared.HandlerManager; import com.google.web.bindery.event.shared.HandlerRegistration; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.FastStringMap; +import com.vaadin.client.FastStringSet; import com.vaadin.client.JsArrayObject; import com.vaadin.client.Profiler; import com.vaadin.client.ServerConnector; @@ -479,4 +480,27 @@ public abstract class AbstractConnector implements ServerConnector, Set<String> reg = getState().registeredEventListeners; return (reg != null && reg.contains(eventIdentifier)); } + + /** + * Force the connector to recheck its state variables as the variables or + * their meaning might have changed. + * + * @since 7.3 + */ + public void forceStateChange() { + StateChangeEvent event = new FullStateChangeEvent(this); + fireEvent(event); + } + + private static class FullStateChangeEvent extends StateChangeEvent { + public FullStateChangeEvent(ServerConnector connector) { + super(connector, FastStringSet.create()); + } + + @Override + public boolean hasPropertyChanged(String property) { + return true; + } + + } } diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java index eaa2292c69..6fc06bb153 100644 --- a/client/src/com/vaadin/client/ui/VCalendarPanel.java +++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java @@ -786,6 +786,21 @@ public class VCalendarPanel extends FocusableFlexTable implements * Updates the calendar and text field with the selected dates. */ public void renderCalendar() { + renderCalendar(true); + } + + /** + * For internal use only. May be removed or replaced in the future. + * + * Updates the calendar and text field with the selected dates. + * + * @param updateDate + * The value false prevents setting the selected date of the + * calendar based on focusedDate. That can be used when only the + * resolution of the calendar is changed and no date has been + * selected. + */ + public void renderCalendar(boolean updateDate) { super.setStylePrimaryName(parent.getStylePrimaryName() + "-calendarpanel"); @@ -798,8 +813,9 @@ public class VCalendarPanel extends FocusableFlexTable implements displayedMonth = new FocusedDate(now.getYear(), now.getMonth(), 1); } - if (getResolution().getCalendarField() <= Resolution.MONTH - .getCalendarField() && focusChangeListener != null) { + if (updateDate + && getResolution().getCalendarField() <= Resolution.MONTH + .getCalendarField() && focusChangeListener != null) { focusChangeListener.focusChanged(new Date(focusedDate.getTime())); } diff --git a/client/src/com/vaadin/client/ui/VContextMenu.java b/client/src/com/vaadin/client/ui/VContextMenu.java index 038ee27dad..1b0181fb7d 100644 --- a/client/src/com/vaadin/client/ui/VContextMenu.java +++ b/client/src/com/vaadin/client/ui/VContextMenu.java @@ -161,6 +161,8 @@ public class VContextMenu extends VOverlay implements SubPartAware { top = top - offsetHeight; if (top < 0) { top = 0; + + setHeight(Window.getClientHeight() + "px"); } } setPopupPosition(left, top); diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 004072d04a..230c9e6639 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -46,6 +46,7 @@ import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.i18n.client.HasDirection.Direction; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -62,6 +63,7 @@ import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ComputedStyle; import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.UIDL; @@ -264,10 +266,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, final Collection<FilterSelectSuggestion> currentSuggestions, final int currentPage, final int totalSuggestions) { - if (enableDebug) { - debug("VFS.SP: showSuggestions(" + currentSuggestions + ", " - + currentPage + ", " + totalSuggestions + ")"); - } + debug("VFS.SP: showSuggestions(" + currentSuggestions + ", " + + currentPage + ", " + totalSuggestions + ")"); /* * We need to defer the opening of the popup so that the parent DOM @@ -316,8 +316,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, status.setInnerText(""); } // We don't need to show arrows or statusbar if there is - // only one - // page + // only one page if (totalSuggestions <= pageLength || pageLength == 0) { setPagingEnabled(false); } else { @@ -332,6 +331,14 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, .clearWidth(); setPopupPositionAndShow(popup); + // Fix for #14173 + // IE9 and IE10 have a bug, when resize an a element with + // box-shadow. + // IE9 and IE10 need explicit update to remove extra + // box-shadows + if (BrowserInfo.get().isIE9() || BrowserInfo.get().isIE10()) { + forceReflow(); + } } }); } @@ -383,18 +390,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ public void selectNextItem() { debug("VFS.SP: selectNextItem()"); - final MenuItem cur = menu.getSelectedItem(); - final int index = 1 + menu.getItems().indexOf(cur); + + final int index = menu.getSelectedIndex() + 1; if (menu.getItems().size() > index) { - final MenuItem newSelectedItem = menu.getItems().get(index); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); - - } else if (hasNextPage()) { - selectPopupItemWhenResponseIsReceived = Select.FIRST; - filterOptions(currentPage + 1, lastFilter); + selectItem(menu.getItems().get(index)); + + } else { + selectNextPage(); } } @@ -403,29 +405,59 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, */ public void selectPrevItem() { debug("VFS.SP: selectPrevItem()"); - final MenuItem cur = menu.getSelectedItem(); - final int index = -1 + menu.getItems().indexOf(cur); + + final int index = menu.getSelectedIndex() - 1; if (index > -1) { - final MenuItem newSelectedItem = menu.getItems().get(index); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); + selectItem(menu.getItems().get(index)); + } else if (index == -1) { - if (currentPage > 0) { - selectPopupItemWhenResponseIsReceived = Select.LAST; - filterOptions(currentPage - 1, lastFilter); - } + selectPrevPage(); + } else { - final MenuItem newSelectedItem = menu.getItems().get( - menu.getItems().size() - 1); - menu.selectItem(newSelectedItem); - tb.setText(newSelectedItem.getText()); - tb.setSelectionRange(lastFilter.length(), newSelectedItem - .getText().length() - lastFilter.length()); + selectItem(menu.getItems().get(menu.getItems().size() - 1)); } } + /** + * Select the first item of the suggestions list popup. + * + * @since + */ + public void selectFirstItem() { + debug("VFS.SP: selectFirstItem()"); + selectItem(menu.getFirstItem()); + } + + /** + * Select the last item of the suggestions list popup. + * + * @since + */ + public void selectLastItem() { + debug("VFS.SP: selectLastItem()"); + selectItem(menu.getLastItem()); + } + + /* + * Sets the selected item in the popup menu. + */ + private void selectItem(final MenuItem newSelectedItem) { + menu.selectItem(newSelectedItem); + + String text = newSelectedItem != null ? newSelectedItem.getText() + : ""; + + // Set the icon. + FilterSelectSuggestion suggestion = (FilterSelectSuggestion) newSelectedItem + .getCommand(); + setSelectedItemIcon(suggestion.getIconUri()); + + // Set the text. + setText(text); + + menu.updateKeyboardSelectedItem(); + } + /* * Using a timer to scroll up or down the pages so when we receive lots * of consecutive mouse wheel events the pages does not flicker. @@ -478,17 +510,10 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt - * .user.client.Event) - */ - @Override public void onBrowserEvent(Event event) { debug("VFS.SP: onBrowserEvent()"); + if (event.getTypeInt() == Event.ONCLICK) { final Element target = DOM.eventGetTarget(event); if (target == up || target == DOM.getChild(up, 0)) { @@ -496,12 +521,24 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } else if (target == down || target == DOM.getChild(down, 0)) { lazyPageScroller.scrollDown(); } + } else if (event.getTypeInt() == Event.ONMOUSEWHEEL) { - int velocity = event.getMouseWheelVelocityY(); - if (velocity > 0) { - lazyPageScroller.scrollDown(); - } else { - lazyPageScroller.scrollUp(); + + boolean scrollNotActive = !menu.isScrollActive(); + + debug("VFS.SP: onBrowserEvent() scrollNotActive: " + + scrollNotActive); + + if (scrollNotActive) { + int velocity = event.getMouseWheelVelocityY(); + + debug("VFS.SP: onBrowserEvent() velocity: " + velocity); + + if (velocity > 0) { + lazyPageScroller.scrollDown(); + } else { + lazyPageScroller.scrollUp(); + } } } @@ -538,32 +575,29 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, isPagingEnabled = paging; } - /* - * (non-Javadoc) - * - * @see - * com.google.gwt.user.client.ui.PopupPanel$PositionCallback#setPosition - * (int, int) - */ - @Override public void setPosition(int offsetWidth, int offsetHeight) { - debug("VFS.SP: setPosition()"); + debug("VFS.SP: setPosition(" + offsetWidth + ", " + offsetHeight + + ")"); - int top = -1; - int left = -1; + int top = topPosition; + int left = getPopupLeft(); // reset menu size and retrieve its "natural" size menu.setHeight(""); - if (currentPage > 0) { + if (currentPage > 0 && !hasNextPage()) { // fix height to avoid height change when getting to last page menu.fixHeightTo(pageLength); } - offsetHeight = getOffsetHeight(); + final int desiredHeight = offsetHeight = getOffsetHeight(); final int desiredWidth = getMainWidth(); + + debug("VFS.SP: desired[" + desiredWidth + ", " + desiredHeight + + "]"); + Element menuFirstChild = menu.getElement().getFirstChildElement(); - int naturalMenuWidth = menuFirstChild.getOffsetWidth(); + final int naturalMenuWidth = menuFirstChild.getOffsetWidth(); if (popupOuterPadding == -1) { popupOuterPadding = Util.measureHorizontalPaddingAndBorder( @@ -573,7 +607,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (naturalMenuWidth < desiredWidth) { menu.setWidth((desiredWidth - popupOuterPadding) + "px"); menuFirstChild.getStyle().setWidth(100, Unit.PCT); - naturalMenuWidth = desiredWidth; } if (BrowserInfo.get().isIE()) { @@ -581,43 +614,67 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * IE requires us to specify the width for the container * element. Otherwise it will be 100% wide */ - int rootWidth = naturalMenuWidth - popupOuterPadding; + int rootWidth = Math.max(desiredWidth, naturalMenuWidth) + - popupOuterPadding; getContainerElement().getStyle().setWidth(rootWidth, Unit.PX); } - if (offsetHeight + getPopupTop() > Window.getClientHeight() - + Window.getScrollTop()) { + final int vfsHeight = VFilterSelect.this.getOffsetHeight(); + final int spaceAvailableAbove = top - vfsHeight; + final int spaceAvailableBelow = Window.getClientHeight() - top; + if (spaceAvailableBelow < offsetHeight + && spaceAvailableBelow < spaceAvailableAbove) { // popup on top of input instead - top = getPopupTop() - offsetHeight - - VFilterSelect.this.getOffsetHeight(); + top -= offsetHeight + vfsHeight; if (top < 0) { + offsetHeight += top; top = 0; } } else { - top = getPopupTop(); - /* - * Take popup top margin into account. getPopupTop() returns the - * top value including the margin but the value we give must not - * include the margin. - */ - int topMargin = (top - topPosition); - top -= topMargin; + offsetHeight = Math.min(offsetHeight, spaceAvailableBelow); } // fetch real width (mac FF bugs here due GWT popups overflow:auto ) offsetWidth = menuFirstChild.getOffsetWidth(); - if (offsetWidth + getPopupLeft() > Window.getClientWidth() - + Window.getScrollLeft()) { + + if (offsetHeight < desiredHeight) { + int menuHeight = offsetHeight; + if (isPagingEnabled) { + menuHeight -= up.getOffsetHeight() + down.getOffsetHeight() + + status.getOffsetHeight(); + } else { + final ComputedStyle s = new ComputedStyle(menu.getElement()); + menuHeight -= s.getIntProperty("marginBottom") + + s.getIntProperty("marginTop"); + } + + // If the available page height is really tiny then this will be + // negative and an exception will be thrown on setHeight. + int menuElementHeight = menu.getItemOffsetHeight(); + if (menuHeight < menuElementHeight) { + menuHeight = menuElementHeight; + } + + menu.setHeight(menuHeight + "px"); + + final int naturalMenuWidthPlusScrollBar = naturalMenuWidth + + Util.getNativeScrollbarSize(); + if (offsetWidth < naturalMenuWidthPlusScrollBar) { + menu.setWidth(naturalMenuWidthPlusScrollBar + "px"); + } + } + + if (offsetWidth + left > Window.getClientWidth()) { left = VFilterSelect.this.getAbsoluteLeft() - + VFilterSelect.this.getOffsetWidth() - + Window.getScrollLeft() - offsetWidth; + + VFilterSelect.this.getOffsetWidth() - offsetWidth; if (left < 0) { left = 0; + menu.setWidth(Window.getClientWidth() + "px"); } - } else { - left = getPopupLeft(); } + setPopupPosition(left, top); + menu.scrollSelectionIntoView(); } /** @@ -715,17 +772,28 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, super(true); debug("VFS.SM: constructor()"); addDomHandler(this, LoadEvent.getType()); + + setScrollEnabled(true); } /** * Fixes menus height to use same space as full page would use. Needed - * to avoid height changes when quickly "scrolling" to last page + * to avoid height changes when quickly "scrolling" to last page. */ - public void fixHeightTo(int pagelenth) { + public void fixHeightTo(int pageItemsCount) { + setHeight(getPreferredHeight(pageItemsCount)); + } + + /* + * Gets the preferred height of the menu including pageItemsCount items. + */ + String getPreferredHeight(int pageItemsCount) { if (currentSuggestions.size() > 0) { - final int pixels = pagelenth * (getOffsetHeight() - 2) - / currentSuggestions.size(); - setHeight((pixels + 2) + "px"); + final int pixels = (getPreferredHeight() / currentSuggestions + .size()) * pageItemsCount; + return pixels + "px"; + } else { + return ""; } } @@ -781,6 +849,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, client.updateVariable(paintableId, "page", 0, false); client.updateVariable(paintableId, "selected", new String[] {}, immediate); + afterUpdateClientVariables(); + suggestionPopup.hide(); return; } @@ -829,6 +899,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, lastNewItemString = enteredItemValue; client.updateVariable(paintableId, "newitem", enteredItemValue, immediate); + afterUpdateClientVariables(); } } else if (item != null && !"".equals(lastFilter) @@ -844,11 +915,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, && !currentSuggestion.key.equals("")) { // An item (not null) selected String text = currentSuggestion.getReplacementString(); - tb.setText(text); + setText(text); selectedOptionKey = currentSuggestion.key; } else { // Null selected - tb.setText(""); + setText(""); selectedOptionKey = null; } } @@ -901,26 +972,75 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } - public void selectFirstItem() { - debug("VFS.SM: selectFirstItem()"); - MenuItem firstItem = getItems().get(0); - selectItem(firstItem); - } - private MenuItem getKeyboardSelectedItem() { return keyboardSelectedItem; } - public void setKeyboardSelectedItem(MenuItem firstItem) { - keyboardSelectedItem = firstItem; + public void setKeyboardSelectedItem(MenuItem menuItem) { + keyboardSelectedItem = menuItem; + } + + /** + * @deprecated use {@link SuggestionPopup#selectFirstItem()} instead. + */ + @Deprecated + public void selectFirstItem() { + debug("VFS.SM: selectFirstItem()"); + MenuItem firstItem = getItems().get(0); + selectItem(firstItem); } + /** + * @deprecated use {@link SuggestionPopup#selectLastItem()} instead. + */ + @Deprecated public void selectLastItem() { debug("VFS.SM: selectLastItem()"); List<MenuItem> items = getItems(); MenuItem lastItem = items.get(items.size() - 1); selectItem(lastItem); } + + /* + * Sets the keyboard item as the current selected one. + */ + void updateKeyboardSelectedItem() { + setKeyboardSelectedItem(getSelectedItem()); + } + + /* + * Gets the height of one menu item. + */ + int getItemOffsetHeight() { + List<MenuItem> items = getItems(); + return items != null && items.size() > 0 ? items.get(0) + .getOffsetHeight() : 0; + } + + /* + * Gets the width of one menu item. + */ + int getItemOffsetWidth() { + List<MenuItem> items = getItems(); + return items != null && items.size() > 0 ? items.get(0) + .getOffsetWidth() : 0; + } + + /** + * Returns true if the scroll is active on the menu element or if the + * menu currently displays the last page with less items then the + * maximum visibility (in which case the scroll is not active, but the + * scroll is active for any other page in general). + */ + @Override + public boolean isScrollActive() { + String height = getElement().getStyle().getHeight(); + String preferredHeight = getPreferredHeight(pageLength); + + return !(height == null || height.length() == 0 || height + .equals(preferredHeight)); + } + } /** @@ -937,11 +1057,33 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, @Override public void setSelectionRange(int pos, int length) { if (textInputEnabled) { - super.setSelectionRange(pos, length); + /* + * set selection range with a backwards direction: anchor at the + * back, focus at the front. This means that items that are too + * long to display will display from the start and not the end + * even on Firefox. + * + * We need the JSNI function to set selection range so that we + * can use the optional direction attribute to set the anchor to + * the end and the focus to the start. This makes Firefox work + * the same way as other browsers (#13477) + */ + Util.setSelectionRange(getElement(), pos, length, "backward"); + } else { - super.setSelectionRange(getValue().length(), 0); + /* + * Setting the selectionrange for an uneditable textbox leads to + * unwanted behaviour when the width of the textbox is narrower + * than the width of the entry: the end of the entry is shown + * instead of the beginning. (see #13477) + * + * To avoid this, we set the caret to the beginning of the line. + */ + + super.setSelectionRange(0, 0); } } + } @Deprecated @@ -1265,10 +1407,9 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * Whether to send the options request immediately */ private void filterOptions(int page, String filter, boolean immediate) { - if (enableDebug) { - debug("VFS: filterOptions(" + page + ", " + filter + ", " - + immediate + ")"); - } + debug("VFS: filterOptions(" + page + ", " + filter + ", " + immediate + + ")"); + if (filter.equals(lastFilter) && currentPage == page) { if (!suggestionPopup.isAttached()) { suggestionPopup.showSuggestions(currentSuggestions, @@ -1289,8 +1430,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, waitingForFilteringResponse = true; client.updateVariable(paintableId, "filter", filter, false); client.updateVariable(paintableId, "page", page, immediate); + afterUpdateClientVariables(); + lastFilter = filter; currentPage = page; + } /** For internal use only. May be removed or replaced in the future. */ @@ -1329,7 +1473,18 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (enableDebug) { debug("VFS: setTextboxText(" + text + ")"); } + setText(text); + } + + private void setText(final String text) { + /** + * To leave caret in the beginning of the line. SetSelectionRange + * wouldn't work on IE (see #13477) + */ + Direction previousDirection = tb.getDirection(); + tb.setDirection(Direction.RTL); tb.setText(text); + tb.setDirection(previousDirection); } /** @@ -1393,10 +1548,13 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, setPromptingOff(text); } setSelectedItemIcon(suggestion.getIconUri()); + if (!(newKey.equals(selectedOptionKey) || ("".equals(newKey) && selectedOptionKey == null))) { selectedOptionKey = newKey; client.updateVariable(paintableId, "selected", new String[] { selectedOptionKey }, immediate); + afterUpdateClientVariables(); + // currentPage = -1; // forget the page } suggestionPopup.hide(); @@ -1589,28 +1747,22 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, switch (event.getNativeKeyCode()) { case KeyCodes.KEY_DOWN: suggestionPopup.selectNextItem(); - suggestionPopup.menu.setKeyboardSelectedItem(suggestionPopup.menu - .getSelectedItem()); + DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); event.stopPropagation(); break; case KeyCodes.KEY_UP: suggestionPopup.selectPrevItem(); - suggestionPopup.menu.setKeyboardSelectedItem(suggestionPopup.menu - .getSelectedItem()); + DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); event.stopPropagation(); break; case KeyCodes.KEY_PAGEDOWN: - if (hasNextPage()) { - filterOptions(currentPage + 1, lastFilter); - } + selectNextPage(); event.stopPropagation(); break; case KeyCodes.KEY_PAGEUP: - if (currentPage > 0) { - filterOptions(currentPage - 1, lastFilter); - } + selectPrevPage(); event.stopPropagation(); break; case KeyCodes.KEY_TAB: @@ -1632,10 +1784,14 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (!allowNewItem) { /* * New items are not allowed: If there is only one - * suggestion, select that. Otherwise do nothing. + * suggestion, select that. If there is more than one + * suggestion Enter key should work as Escape key. Otherwise + * do nothing. */ if (currentSuggestions.size() == 1) { onSuggestionSelected(currentSuggestions.get(0)); + } else if (currentSuggestions.size() > 1) { + reset(); } } else { // Handle addition of new items. @@ -1656,6 +1812,26 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, } + /* + * Show the prev page. + */ + private void selectPrevPage() { + if (currentPage > 0) { + filterOptions(currentPage - 1, lastFilter); + selectPopupItemWhenResponseIsReceived = Select.LAST; + } + } + + /* + * Show the next page. + */ + private void selectNextPage() { + if (hasNextPage()) { + filterOptions(currentPage + 1, lastFilter); + selectPopupItemWhenResponseIsReceived = Select.FIRST; + } + } + /** * Triggered when a key was depressed * @@ -1699,15 +1875,21 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (currentSuggestion != null) { String text = currentSuggestion.getReplacementString(); setPromptingOff(text); + setSelectedItemIcon(currentSuggestion.getIconUri()); + selectedOptionKey = currentSuggestion.key; + } else { if (focused || readonly || !enabled) { setPromptingOff(""); } else { setPromptingOn(); } + setSelectedItemIcon(null); + selectedOptionKey = null; } + lastFilter = ""; suggestionPopup.hide(); } @@ -1829,6 +2011,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (client.hasEventListeners(this, EventId.FOCUS)) { client.updateVariable(paintableId, EventId.FOCUS, "", true); + afterUpdateClientVariables(); } ComponentConnector connector = ConnectorMap.get(client).getConnector( @@ -1905,6 +2088,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (client.hasEventListeners(this, EventId.BLUR)) { client.updateVariable(paintableId, EventId.BLUR, "", true); + afterUpdateClientVariables(); } } @@ -2083,4 +2267,15 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, com.google.gwt.user.client.Element captionElement) { AriaHelper.bindCaption(tb, captionElement); } + + /* + * Anything that should be set after the client updates the server. + */ + private void afterUpdateClientVariables() { + // We need this here to be consistent with the all the calls. + // Then set your specific selection type only after + // client.updateVariable() method call. + selectPopupItemWhenResponseIsReceived = Select.NONE; + } + } diff --git a/client/src/com/vaadin/client/ui/VGridLayout.java b/client/src/com/vaadin/client/ui/VGridLayout.java index 10e5c00a38..17131ce63b 100644 --- a/client/src/com/vaadin/client/ui/VGridLayout.java +++ b/client/src/com/vaadin/client/ui/VGridLayout.java @@ -95,7 +95,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the column widths measured in pixels - * + * * @return */ protected int[] getColumnWidths() { @@ -104,7 +104,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the row heights measured in pixels - * + * * @return */ protected int[] getRowHeights() { @@ -113,7 +113,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells horizontally in pixels - * + * * @return */ protected int getHorizontalSpacing() { @@ -122,7 +122,7 @@ public class VGridLayout extends ComplexPanel { /** * Returns the spacing between the cells vertically in pixels - * + * * @return */ protected int getVerticalSpacing() { @@ -271,7 +271,7 @@ public class VGridLayout extends ComplexPanel { } for (SpanList l : rowSpans) { for (Cell cell : l.cells) { - if (cell.row >= i && i < cell.row + cell.rowspan) { + if (cell.row <= i && i < cell.row + cell.rowspan) { return true; } } @@ -287,7 +287,7 @@ public class VGridLayout extends ComplexPanel { } for (SpanList l : colSpans) { for (Cell cell : l.cells) { - if (cell.col >= i && i < cell.col + cell.colspan) { + if (cell.col <= i && i < cell.col + cell.colspan) { return true; } } @@ -751,7 +751,7 @@ public class VGridLayout extends ComplexPanel { * Creates a new Cell with the given coordinates. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param row * @param col * @return @@ -767,7 +767,7 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout @@ -788,13 +788,13 @@ public class VGridLayout extends ComplexPanel { * child component is also returned if "element" is part of its caption. * <p> * For internal use only. May be removed or replaced in the future. - * + * * @param element * An element that is a nested sub element of the root element in * this layout * @return The Paintable which the element is a part of. Null if the element * belongs to the layout and not to a child. - * + * * @since 7.2 */ public ComponentConnector getComponent(Element element) { diff --git a/client/src/com/vaadin/client/ui/VNativeButton.java b/client/src/com/vaadin/client/ui/VNativeButton.java index 93d8d958d6..8e0dd2bce1 100644 --- a/client/src/com/vaadin/client/ui/VNativeButton.java +++ b/client/src/com/vaadin/client/ui/VNativeButton.java @@ -104,7 +104,9 @@ public class VNativeButton extends Button implements ClickHandler { } clickPending = false; } else if (event.getTypeInt() == Event.ONFOCUS) { - if (BrowserInfo.get().isIE() && clickPending) { + if (BrowserInfo.get().isIE() + && BrowserInfo.get().getBrowserMajorVersion() < 11 + && clickPending) { /* * The focus event will mess up IE and IE will not trigger the * mouse up event (which in turn triggers the click event) until diff --git a/client/src/com/vaadin/client/ui/VNotification.java b/client/src/com/vaadin/client/ui/VNotification.java index af7e429340..3cc1afd5ba 100644 --- a/client/src/com/vaadin/client/ui/VNotification.java +++ b/client/src/com/vaadin/client/ui/VNotification.java @@ -81,6 +81,8 @@ public class VNotification extends VOverlay { private boolean infiniteDelay = false; private int hideDelay = 0; + private Timer delay; + private int x = -1; private int y = -1; @@ -260,8 +262,23 @@ public class VNotification extends VOverlay { } } + protected void hideAfterDelay() { + if (delay == null) { + delay = new Timer() { + @Override + public void run() { + VNotification.super.hide(); + } + }; + delay.schedule(hideDelay); + } + } + @Override public void hide() { + if (delay != null) { + delay.cancel(); + } // Run only once if (notifications.contains(this)) { DOM.removeEventPreview(this); @@ -284,23 +301,7 @@ public class VNotification extends VOverlay { } }); } else { - // Use a timer in browsers without CSS animation support - // to show the notification for the duration of the delay - if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9()) { - new Timer() { - @Override - public void run() { - VNotification.super.hide(); - } - }.schedule(hideDelay); - } else { - if (hideDelay > 0) { - AnimationUtil.setAnimationDelay(getElement(), hideDelay - + "ms"); - } - VNotification.super.hide(); - - } + VNotification.super.hide(); fireEvent(new HideEvent(this)); notifications.remove(this); } @@ -416,19 +417,19 @@ public class VNotification extends VOverlay { y = DOM.eventGetClientY(event); } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) { - hide(); + hideAfterDelay(); } break; case Event.ONMOUSEDOWN: case Event.ONMOUSEWHEEL: case Event.ONSCROLL: - hide(); + hideAfterDelay(); break; case Event.ONKEYDOWN: if (event.getRepeat()) { return true; } - hide(); + hideAfterDelay(); break; default: break; diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index f9aa2ef2f8..afa13dc337 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -444,7 +444,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * A "thread local" of sorts, set temporarily so that VOverlayImpl knows * which VOverlay is using it, so that it can be attached to the correct * overlay container. - * + * * TODO this is a strange pattern that we should get rid of when possible. */ protected static VOverlay current; @@ -656,6 +656,12 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { } } } + // Fix for #14173 + // IE9 and IE10 have a bug, when resize an a element with box-shadow. + // IE9 and IE10 need explicit update to remove extra box-shadows + if (BrowserInfo.get().isIE9() || BrowserInfo.get().isIE10()) { + Util.forceIERedraw(getElement()); + } } /** @@ -875,7 +881,9 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { container.setId(id); String styles = ac.getUIConnector().getWidget().getParent() .getStyleName(); - container.addClassName(styles); + if (styles != null && !styles.equals("")) { + container.addClassName(styles); + } container.addClassName(CLASSNAME_CONTAINER); RootPanel.get().getElement().appendChild(container); } @@ -965,7 +973,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide() */ @Override @@ -975,7 +983,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { /* * (non-Javadoc) - * + * * @see com.google.gwt.user.client.ui.PopupPanel#hide(boolean) */ @Override @@ -1053,4 +1061,4 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { } } } -}
\ No newline at end of file +} diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index 7dea959bb4..1474ad3b71 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -145,7 +145,7 @@ public class VPopupCalendar extends VTextualDate implements Field, } }); - popup = new VOverlay(true, true, true); + popup = new VOverlay(true, false, true); popup.setOwner(this); FlowPanel wrapper = new FlowPanel(); diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index ef8be5aadc..c1e83ef08b 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -47,8 +47,6 @@ import com.google.gwt.dom.client.TableSectionElement; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.event.dom.client.ContextMenuEvent; -import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.KeyCodes; @@ -80,6 +78,7 @@ import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorMap; +import com.vaadin.client.DeferredWorker; import com.vaadin.client.Focusable; import com.vaadin.client.MouseEventDetailsBuilder; import com.vaadin.client.StyleConstants; @@ -126,7 +125,138 @@ import com.vaadin.shared.ui.table.TableConstants; */ public class VScrollTable extends FlowPanel implements HasWidgets, ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable, - ActionOwner, SubPartAware { + ActionOwner, SubPartAware, DeferredWorker { + + /** + * Simple interface for parts of the table capable of owning a context menu. + * + * @since 7.2 + * @author Vaadin Ltd + */ + private interface ContextMenuOwner { + public void showContextMenu(Event event); + } + + /** + * Handles showing context menu on "long press" from a touch screen. + * + * @since 7.2 + * @author Vaadin Ltd + */ + private class TouchContextProvider { + private static final int TOUCH_CONTEXT_MENU_TIMEOUT = 500; + private Timer contextTouchTimeout; + + private Event touchStart; + private int touchStartY; + private int touchStartX; + + private ContextMenuOwner target; + + /** + * Initializes a handler for a certain context menu owner. + * + * @param target + * the owner of the context menu + */ + public TouchContextProvider(ContextMenuOwner target) { + this.target = target; + } + + /** + * Cancels the current context touch timeout. + */ + public void cancel() { + if (contextTouchTimeout != null) { + contextTouchTimeout.cancel(); + contextTouchTimeout = null; + } + touchStart = null; + } + + /** + * A function to handle touch context events in a table. + * + * @param event + * browser event to handle + */ + public void handleTouchEvent(final Event event) { + int type = event.getTypeInt(); + + switch (type) { + case Event.ONCONTEXTMENU: + target.showContextMenu(event); + break; + case Event.ONTOUCHSTART: + // save position to fields, touches in events are same + // instance during the operation. + touchStart = event; + + Touch touch = event.getChangedTouches().get(0); + touchStartX = touch.getClientX(); + touchStartY = touch.getClientY(); + + if (contextTouchTimeout == null) { + contextTouchTimeout = new Timer() { + + @Override + public void run() { + if (touchStart != null) { + // Open the context menu if finger + // is held in place long enough. + target.showContextMenu(touchStart); + event.preventDefault(); + touchStart = null; + } + } + }; + } + contextTouchTimeout.schedule(TOUCH_CONTEXT_MENU_TIMEOUT); + break; + case Event.ONTOUCHCANCEL: + case Event.ONTOUCHEND: + cancel(); + break; + case Event.ONTOUCHMOVE: + if (isSignificantMove(event)) { + // Moved finger before the context menu timer + // expired, so let the browser handle the event. + cancel(); + } + } + } + + /** + * Calculates how many pixels away the user's finger has traveled. This + * reduces the chance of small non-intentional movements from canceling + * the long press detection. + * + * @param event + * the Event for which to check the move distance + * @return true if this is considered an intentional move by the user + */ + protected boolean isSignificantMove(Event event) { + if (touchStart == null) { + // no touch start + return false; + } + + // Calculate the distance between touch start and the current touch + // position + Touch touch = event.getChangedTouches().get(0); + int deltaX = touch.getClientX() - touchStartX; + int deltaY = touch.getClientY() - touchStartY; + int delta = deltaX * deltaX + deltaY * deltaY; + + // Compare to the square of the significant move threshold to remove + // the need for a square root + if (delta > TouchScrollDelegate.SIGNIFICANT_MOVE_THRESHOLD + * TouchScrollDelegate.SIGNIFICANT_MOVE_THRESHOLD) { + return true; + } + return false; + } + } public static final String STYLENAME = "v-table"; @@ -195,6 +325,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** For internal use only. May be removed or replaced in the future. */ public boolean immediate; + private boolean updatedReqRows = true; + private boolean nullSelectionAllowed = true; private SelectMode selectMode = SelectMode.NONE; @@ -369,8 +501,49 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** For internal use only. May be removed or replaced in the future. */ public final TableFooter tFoot = new TableFooter(); + /** Handles context menu for table body */ + private ContextMenuOwner contextMenuOwner = new ContextMenuOwner() { + + @Override + public void showContextMenu(Event event) { + int left = Util.getTouchOrMouseClientX(event); + int top = Util.getTouchOrMouseClientY(event); + boolean menuShown = handleBodyContextMenu(left, top); + if (menuShown) { + event.stopPropagation(); + event.preventDefault(); + } + } + }; + + /** Handles touch events to display a context menu for table body */ + private TouchContextProvider touchContextProvider = new TouchContextProvider( + contextMenuOwner); + + /** + * For internal use only. May be removed or replaced in the future. + * + * Overwrites onBrowserEvent function on FocusableScrollPanel to give event + * access to touchContextProvider. Has to be public to give TableConnector + * access to the scrollBodyPanel field. + * + * @since 7.2 + * @author Vaadin Ltd + */ + public class FocusableScrollContextPanel extends FocusableScrollPanel { + @Override + public void onBrowserEvent(Event event) { + super.onBrowserEvent(event); + touchContextProvider.handleTouchEvent(event); + }; + + public FocusableScrollContextPanel(boolean useFakeFocusElement) { + super(useFakeFocusElement); + } + } + /** For internal use only. May be removed or replaced in the future. */ - public final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel( + public final FocusableScrollContextPanel scrollBodyPanel = new FocusableScrollContextPanel( true); private KeyPressHandler navKeyPressHandler = new KeyPressHandler() { @@ -588,6 +761,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private boolean hadScrollBars = false; + private HandlerRegistration addCloseHandler; + public VScrollTable() { setMultiSelectMode(MULTISELECT_MODE_DEFAULT); @@ -608,16 +783,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } scrollBodyPanel.addKeyUpHandler(navKeyUpHandler); - scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS); - - scrollBodyPanel.sinkEvents(Event.ONCONTEXTMENU); - scrollBodyPanel.addDomHandler(new ContextMenuHandler() { - - @Override - public void onContextMenu(ContextMenuEvent event) { - handleBodyContextMenu(event); - } - }, ContextMenuEvent.getType()); + scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS | Event.ONCONTEXTMENU); setStyleName(STYLENAME); @@ -669,28 +835,33 @@ public class VScrollTable extends FlowPanel implements HasWidgets, this.client = client; // Add a handler to clear saved context menu details when the menu // closes. See #8526. - client.getContextMenu().addCloseHandler(new CloseHandler<PopupPanel>() { + addCloseHandler = client.getContextMenu().addCloseHandler( + new CloseHandler<PopupPanel>() { - @Override - public void onClose(CloseEvent<PopupPanel> event) { - contextMenu = null; - } - }); + @Override + public void onClose(CloseEvent<PopupPanel> event) { + contextMenu = null; + } + }); } - private void handleBodyContextMenu(ContextMenuEvent event) { + /** + * Handles a context menu event on table body. + * + * @param left + * left position of the context menu + * @param top + * top position of the context menu + * @return true if a context menu was shown, otherwise false + */ + private boolean handleBodyContextMenu(int left, int top) { if (enabled && bodyActionKeys != null) { - int left = Util.getTouchOrMouseClientX(event.getNativeEvent()); - int top = Util.getTouchOrMouseClientY(event.getNativeEvent()); top += Window.getScrollTop(); left += Window.getScrollLeft(); client.getContextMenu().showAt(this, left, top); - - // Only prevent browser context menu if there are action handlers - // registered - event.stopPropagation(); - event.preventDefault(); + return true; } + return false; } /** @@ -1174,7 +1345,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, @Override public void execute() { - if (firstvisible > 0) { + if (firstvisible >= 0) { firstRowInViewPort = firstvisible; if (firstvisibleOnLastPage > -1) { scrollBodyPanel @@ -2248,13 +2419,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * Ensures the column alignments are correct at initial loading. <br/> * (child components widths are correct) */ - Scheduler.get().scheduleDeferred(new Command() { - - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); hadScrollBars = willHaveScrollbarz; } @@ -2395,6 +2560,27 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // if client connection is busy, don't bother loading it more VConsole.log("Postponed rowfetch"); schedule(250); + } else if (!updatedReqRows && allRenderedRowsAreNew()) { + + /* + * If all rows are new, there might have been a server-side call + * to Table.setCurrentPageFirstItemIndex(int) In this case, + * scrolling event takes way too late, and all the rows from + * previous viewport to this one were requested. + * + * This should prevent requesting unneeded rows by updating + * reqFirstRow and reqRows before needing them. See (#14135) + */ + + setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate))); + int last = firstRowInViewPort + (int) (cache_rate * pageLength) + + pageLength - 1; + if (last >= totalRows) { + last = totalRows - 1; + } + setReqRows(last - getReqFirstRow() + 1); + updatedReqRows = true; + schedule(250); } else { int firstRendered = scrollBody.getFirstRendered(); @@ -5115,7 +5301,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return -1; } - public class VScrollTableRow extends Panel implements ActionOwner { + public class VScrollTableRow extends Panel implements ActionOwner, + ContextMenuOwner { private static final int TOUCHSCROLL_TIMEOUT = 100; private static final int DRAGMODE_MULTIROW = 2; @@ -5133,6 +5320,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private Timer dragTouchTimeout; private int touchStartY; private int touchStartX; + + private TouchContextProvider touchContextProvider = new TouchContextProvider( + this); + private TooltipInfo tooltipInfo = null; private Map<TableCellElement, TooltipInfo> cellToolTips = new HashMap<TableCellElement, TooltipInfo>(); private boolean isDragging = false; @@ -5588,6 +5779,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, boolean touchEventHandled = false; if (enabled && hasNativeTouchScrolling) { + touchContextProvider.handleTouchEvent(event); + final Element targetTdOrTr = getEventTargetTdOrTr(event); final int type = event.getTypeInt(); @@ -5848,9 +6041,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, Util.simulateClickFromTouchEvent(touchStart, this); touchStart = null; } - if (contextTouchTimeout != null) { - contextTouchTimeout.cancel(); - } + touchContextProvider.cancel(); break; case Event.ONTOUCHMOVE: if (isSignificantMove(event)) { @@ -5865,9 +6056,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, .getActiveScrollDelegate() == null)) { startRowDrag(touchStart, type, targetTdOrTr); } - if (contextTouchTimeout != null) { - contextTouchTimeout.cancel(); - } + touchContextProvider.cancel(); /* * Avoid clicks and drags by clearing touch start * flag. @@ -6103,6 +6292,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return getTdOrTr(eventTarget); } + @Override public void showContextMenu(Event event) { if (enabled && actionKeys != null) { // Show context menu if there are registered action handlers @@ -6717,13 +6907,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, Util.notifyParentOfSizeChange(VScrollTable.this, rendering); } } - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); forceRealignColumnHeaders(); } @@ -6860,13 +7045,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // We must run the fix as a deferred command to prevent it from // overwriting the scroll position with an outdated value, see // #7607. - Scheduler.get().scheduleDeferred(new Command() { - - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement()); } triggerLazyColumnAdjustment(false); @@ -7011,8 +7190,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return; } - if (firstRowInViewPort - pageLength * cache_rate > lastRendered - || firstRowInViewPort + pageLength + pageLength * cache_rate < firstRendered) { + if (allRenderedRowsAreNew()) { // need a totally new set of rows rowRequestHandler .setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate))); @@ -7023,6 +7201,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } rowRequestHandler.setReqRows(last - rowRequestHandler.getReqFirstRow() + 1); + updatedReqRows = false; rowRequestHandler.deferRowFetch(); return; } @@ -7045,6 +7224,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + private boolean allRenderedRowsAreNew() { + int firstRowInViewPort = calcFirstRowInViewPort(); + int firstRendered = scrollBody.getFirstRendered(); + int lastRendered = scrollBody.getLastRendered(); + return (firstRowInViewPort - pageLength * cache_rate > lastRendered || firstRowInViewPort + + pageLength + pageLength * cache_rate < firstRendered); + } + protected int calcFirstRowInViewPort() { return (int) Math.ceil(scrollTop / scrollBody.getRowHeight()); } @@ -7929,4 +8116,21 @@ public class VScrollTable extends FlowPanel implements HasWidgets, // Nothing found. return null; } + + /** + * @since + */ + public void onUnregister() { + if (addCloseHandler != null) { + addCloseHandler.removeHandler(); + } + } + + /* + * Return true if component need to perform some work and false otherwise. + */ + @Override + public boolean isWorkPending() { + return lazyAdjustColumnWidths.isRunning(); + } } diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index 15d9c83c49..a2a6889e15 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -42,9 +42,12 @@ import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.HasBlurHandlers; import com.google.gwt.event.dom.client.HasFocusHandlers; import com.google.gwt.event.dom.client.HasKeyDownHandlers; +import com.google.gwt.event.dom.client.HasMouseDownHandlers; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.regexp.shared.MatchResult; import com.google.gwt.regexp.shared.RegExp; @@ -74,7 +77,9 @@ import com.vaadin.shared.ui.tabsheet.TabsheetServerRpc; import com.vaadin.shared.ui.tabsheet.TabsheetState; public class VTabsheet extends VTabsheetBase implements Focusable, - FocusHandler, BlurHandler, KeyDownHandler, SubPartAware { + SubPartAware, + // TODO: These listeners are due to be removed in 7.3 + FocusHandler, BlurHandler, KeyDownHandler { private static class VCloseEvent { private Tab tab; @@ -95,10 +100,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Representation of a single "tab" shown in the TabBar - * + * */ public static class Tab extends SimplePanel implements HasFocusHandlers, - HasBlurHandlers, HasKeyDownHandlers { + HasBlurHandlers, HasMouseDownHandlers, HasKeyDownHandlers { private static final String TD_CLASSNAME = CLASSNAME + "-tabitemcell"; private static final String TD_FIRST_CLASSNAME = TD_CLASSNAME + "-first"; @@ -152,10 +157,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable, Roles.getTabRole().setAriaLabelledbyProperty(getElement(), Id.of(tabCaption.getElement())); - - addFocusHandler(getTabsheet()); - addBlurHandler(getTabsheet()); - addKeyDownHandler(getTabsheet()); } public boolean isHiddenOnServer() { @@ -197,7 +198,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Toggles the style names for the Tab - * + * * @param selected * true if the Tab is selected * @param first @@ -282,6 +283,11 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } @Override + public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) { + return addDomHandler(handler, MouseDownEvent.getType()); + } + + @Override public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) { return addDomHandler(handler, KeyDownEvent.getType()); } @@ -420,8 +426,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } - static class TabBar extends ComplexPanel implements ClickHandler, - VCloseHandler { + static class TabBar extends ComplexPanel implements VCloseHandler { private final Element tr = DOM.createTR(); @@ -443,6 +448,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, setStyleName(spacerTd, CLASSNAME + "-spacertd"); DOM.appendChild(tr, spacerTd); DOM.appendChild(spacerTd, DOM.createDiv()); + setElement(el); } @@ -460,10 +466,20 @@ public class VTabsheet extends VTabsheetBase implements Focusable, return DOM.asOld(tr); } + /** + * Gets the number of tabs from the tab bar. + * + * @return the number of tabs from the tab bar. + */ public int getTabCount() { return getWidgetCount(); } + /** + * Adds a tab to the tab bar. + * + * @return the added tab. + */ public Tab addTab() { Tab t = new Tab(this); int tabIndex = getTabCount(); @@ -476,31 +492,18 @@ public class VTabsheet extends VTabsheetBase implements Focusable, t.setStyleNames(false, true); } - t.addClickHandler(this); + getTabsheet().selectionHandler.registerTab(t); + t.setCloseHandler(this); return t; } - @Override - public void onClick(ClickEvent event) { - TabCaption caption = (TabCaption) event.getSource(); - Element targetElement = event.getNativeEvent().getEventTarget() - .cast(); - // the tab should not be focused if the close button was clicked - if (targetElement == caption.getCloseButton()) { - return; - } - - int index = getWidgetIndex(caption.getParent()); - - navigateTab(getTabsheet().focusedTabIndex, index); - getTabsheet().focusedTabIndex = index; - getTabsheet().focusedTab = getTab(index); - getTabsheet().focus(); - getTabsheet().loadTabSheet(index); - } - + /** + * Gets the tab sheet instance where the tab bar is attached to. + * + * @return the tab sheet instance where the tab bar is attached to. + */ public VTabsheet getTabsheet() { return tabsheet; } @@ -538,7 +541,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, getTab(tabsheet.activeTabIndex).recalculateCaptionWidth(); } - public void navigateTab(int fromIndex, int toIndex) { + public Tab navigateTab(int fromIndex, int toIndex) { Tab newNavigated = getTab(toIndex); if (newNavigated == null) { throw new IllegalArgumentException( @@ -553,6 +556,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, oldNavigated.setStyleNames(oldNavigated.equals(selected), isFirstVisibleTab(fromIndex), false); } + + return newNavigated; } public void removeTab(int i) { @@ -580,7 +585,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Returns the index of the first visible tab - * + * * @return */ private int getFirstVisibleTab() { @@ -589,7 +594,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Find the next visible tab. Returns -1 if none is found. - * + * * @param i * @return */ @@ -608,7 +613,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Find the previous visible tab. Returns -1 if none is found. - * + * * @param i * @return */ @@ -663,7 +668,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** For internal use only. May be removed or replaced in the future. */ // tabbar and 'scroller' container public final Element tabs; - Tab focusedTab; + /** * The tabindex property (position in the browser's focus cycle.) Named like * this to avoid confusion with activeTabIndex. @@ -697,9 +702,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable, private String currentStyle; - /** For internal use only. May be removed or replaced in the future. */ - private int focusedTabIndex = 0; - /** * @return Whether the tab could be selected or not. */ @@ -720,11 +722,13 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Load the content of a tab of the provided index. - * + * * @param index * of the tab to load + * + * @return true if the specified sheet gets loaded, otherwise false. */ - public void loadTabSheet(int tabIndex) { + public boolean loadTabSheet(int tabIndex) { if (activeTabIndex != tabIndex && canSelectTab(tabIndex)) { tb.selectTab(tabIndex); @@ -741,12 +745,16 @@ public class VTabsheet extends VTabsheetBase implements Focusable, waitingForResponse = true; tb.getTab(tabIndex).focus(); // move keyboard focus to active tab + + return true; } + + return false; } /** * Returns the currently displayed widget in the tab panel. - * + * * @since 7.2 * @return currently displayed content widget */ @@ -756,7 +764,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Returns the client to server RPC proxy for the tabsheet. - * + * * @since 7.2 * @return RPC proxy */ @@ -766,10 +774,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * For internal use only. - * + * * Avoid using this method directly and use appropriate superclass methods * where applicable. - * + * * @deprecated since 7.2 - use more specific methods instead (getRpcProxy(), * getConnectorForWidget(Widget) etc.) * @return ApplicationConnection @@ -799,9 +807,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable, public VTabsheet() { super(CLASSNAME); - addHandler(this, FocusEvent.getType()); - addHandler(this, BlurEvent.getType()); - // Tab scrolling getElement().getStyle().setOverflow(Overflow.HIDDEN); tabs = DOM.createDiv(); @@ -812,18 +817,21 @@ public class VTabsheet extends VTabsheetBase implements Focusable, Roles.getTablistRole().setAriaHiddenState(scroller, true); DOM.setElementProperty(scroller, "className", SCROLLER_CLASSNAME); + scrollerPrev = DOM.createButton(); scrollerPrev.setTabIndex(-1); DOM.setElementProperty(scrollerPrev, "className", SCROLLER_CLASSNAME + "Prev"); Roles.getTablistRole().setAriaHiddenState(scrollerPrev, true); - DOM.sinkEvents(scrollerPrev, Event.ONCLICK); + DOM.sinkEvents(scrollerPrev, Event.ONCLICK | Event.ONMOUSEDOWN); + scrollerNext = DOM.createButton(); scrollerNext.setTabIndex(-1); DOM.setElementProperty(scrollerNext, "className", SCROLLER_CLASSNAME + "Next"); Roles.getTablistRole().setAriaHiddenState(scrollerNext, true); - DOM.sinkEvents(scrollerNext, Event.ONCLICK); + DOM.sinkEvents(scrollerNext, Event.ONCLICK | Event.ONMOUSEDOWN); + DOM.appendChild(getElement(), tabs); // Tabs @@ -856,35 +864,68 @@ public class VTabsheet extends VTabsheetBase implements Focusable, @Override public void onBrowserEvent(Event event) { + com.google.gwt.dom.client.Element eventTarget = DOM + .eventGetTarget(event); + if (event.getTypeInt() == Event.ONCLICK) { + // Tab scrolling - if (isScrolledTabs() && DOM.eventGetTarget(event) == scrollerPrev) { - int newFirstIndex = tb.scrollLeft(scrollerIndex); - if (newFirstIndex != -1) { - scrollerIndex = newFirstIndex; - updateTabScroller(); - } - event.stopPropagation(); - return; - } else if (isClippedTabs() - && DOM.eventGetTarget(event) == scrollerNext) { - int newFirstIndex = tb.scrollRight(scrollerIndex); + if (eventTarget == scrollerPrev || eventTarget == scrollerNext) { + scrollAccordingToScrollTarget(eventTarget); - if (newFirstIndex != -1) { - scrollerIndex = newFirstIndex; - updateTabScroller(); - } event.stopPropagation(); + } + + } else if (event.getTypeInt() == Event.ONMOUSEDOWN) { + + if (eventTarget == scrollerPrev || eventTarget == scrollerNext) { + // In case the focus was previously on a Tab, we need to cancel + // the upcoming blur on the Tab which will follow this mouse + // down event. + focusBlurManager.cancelNextBlurSchedule(); + return; } } + super.onBrowserEvent(event); } + /* + * Scroll the tab bar according to the last scrollTarget (the scroll button + * pressed). + */ + private void scrollAccordingToScrollTarget( + com.google.gwt.dom.client.Element scrollTarget) { + if (scrollTarget == null) { + return; + } + + int newFirstIndex = -1; + + // Scroll left. + if (isScrolledTabs() && scrollTarget == scrollerPrev) { + newFirstIndex = tb.scrollLeft(scrollerIndex); + + // Scroll right. + } else if (isClippedTabs() && scrollTarget == scrollerNext) { + newFirstIndex = tb.scrollRight(scrollerIndex); + } + + if (newFirstIndex != -1) { + scrollerIndex = newFirstIndex; + updateTabScroller(); + } + + // For this to work well, make sure the method gets called only from + // user events. + selectionHandler.focusTabAtIndex(scrollerIndex); + } + /** * Checks if the tab with the selected index has been scrolled out of the * view (on the left side). - * + * * @param index * @return */ @@ -1016,7 +1057,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Renders the widget content for a tab sheet. - * + * * @param newWidget */ public void renderContent(Widget newWidget) { @@ -1239,64 +1280,444 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } @Override - public void onBlur(BlurEvent event) { - getVTooltip().hideTooltip(); + public void focus() { + getActiveTab().focus(); + } - if (focusedTab != null && focusedTab == event.getSource()) { - focusedTab.removeAssistiveDescription(); - focusedTab = null; - if (connector.hasEventListener(EventId.BLUR)) { - connector.getRpcProxy(FocusAndBlurServerRpc.class).blur(); - } - } + public void blur() { + getActiveTab().blur(); } - @Override - public void onFocus(FocusEvent event) { - if (focusedTab == null && event.getSource() instanceof Tab) { - focusedTab = (Tab) event.getSource(); + /* + * Gets the active tab. + */ + private Tab getActiveTab() { + return tb.getTab(activeTabIndex); + } + + /* + * The focus and blur manager instance. + */ + private FocusBlurManager focusBlurManager = new FocusBlurManager(); + + /* + * Manage the TabSheet component blur event. + */ + private class FocusBlurManager implements FocusedTabProvider { + + // The real tab with focus on it. If the focus goes to another element + // in the page this will be null. + private Tab focusedTab; + + @Override + public Tab getFocusedTab() { + return focusedTab; + } + + @Override + public void setFocusedTab(Tab focusedTab) { + this.focusedTab = focusedTab; + } + + /** + * Process the focus event no matter where it occurs on the tab bar. + * We've added this method + * + * @since + * @param newFocusTab + * the new focused tab. + * @see #blur(Tab) + */ + public void focus(Tab newFocusTab) { + if (connector.hasEventListener(EventId.FOCUS)) { - connector.getRpcProxy(FocusAndBlurServerRpc.class).focus(); + + // Send the focus event only first time when we focus on any + // tab. The focused tab will be reseted on the last blur. + if (focusedTab == null) { + connector.getRpcProxy(FocusAndBlurServerRpc.class).focus(); + } } + removeBlurSchedule(); + + setFocusedTab(newFocusTab); + if (focusedTab.hasTooltip()) { focusedTab.setAssistiveDescription(getVTooltip().getUniqueId()); getVTooltip().showAssistive(focusedTab.getTooltipInfo()); } + + } + + /** + * Process the blur event for the current focusedTab. + * + * @param blurSource + * the source of the blur. + * + * @see #focus(Tab) + */ + public void blur(Tab blurSource) { + if (focusedTab != null && focusedTab == blurSource) { + + if (connector.hasEventListener(EventId.BLUR)) { + scheduleBlur(focusedTab); + } + } + } + + /* + * The last blur command to be executed. + */ + private BlurCommand blurCommand; + + /** + * Schedule a new blur event for a deferred execution. + */ + public void scheduleBlur(Tab blurSource) { + + if (cancelNextBlurSchedule) { + + // This will set the stopNextBlurCommand back to false as well. + removeBlurSchedule(); + + // Leave this though to make things clear for the developer. + cancelNextBlurSchedule = false; + return; + } + + removeBlurSchedule(); + + blurCommand = new BlurCommand(blurSource, this); + blurCommand.scheduleDeferred(); + } + + /** + * Remove the last blur command from execution. + */ + public void removeBlurSchedule() { + if (blurCommand != null) { + blurCommand.stopSchedule(); + blurCommand = null; + } + + // Maybe this is not the best place to reset this, but we really + // want to make sure it'll reset at any time when something + // interact with the blur manager. Might change it later. + cancelNextBlurSchedule = false; + } + + /** + * Cancel the next possible scheduled execution. + */ + public void cancelNextBlurSchedule() { + + // Make sure there's still no other command to be executed. + removeBlurSchedule(); + + cancelNextBlurSchedule = true; + } + + // Stupid workaround... + private boolean cancelNextBlurSchedule = false; + + } + + /* + * Wraps the focused tab. + */ + private interface FocusedTabProvider { + + /** + * Gets the focused Tab. + * + * @return the focused Tab. + */ + Tab getFocusedTab(); + + /** + * Sets the focused Tab. + * + * @param focusedTab + * the focused Tab. + */ + void setFocusedTab(Tab focusedTab); + + } + + /* + * Execute the final blur command. + */ + private class BlurCommand implements Command { + + /* + * The blur source. + */ + private Tab blurSource; + + /* + * Provide the current focused Tab. + */ + private FocusedTabProvider focusedTabProvider; + + /** + * Create the blur command using the blur source. + * + * @param blurSource + * the source. + * @param focusedTabProvider + * provides the current focused tab. + */ + public BlurCommand(Tab blurSource, FocusedTabProvider focusedTabProvider) { + this.blurSource = blurSource; + this.focusedTabProvider = focusedTabProvider; + } + + /** + * Stop the command from being executed. + * + * @since + */ + public void stopSchedule() { + blurSource = null; + } + + /** + * Schedule the command for a deferred execution. + * + * @since + */ + public void scheduleDeferred() { + Scheduler.get().scheduleDeferred(this); + } + + @Override + public void execute() { + + Tab focusedTab = focusedTabProvider.getFocusedTab(); + + if (blurSource == null) { + return; + } + + // The focus didn't change since this blur triggered, so + // the new focused element is not a tab. + if (focusedTab == blurSource) { + + // We're certain there's no focus anymore. + focusedTab.removeAssistiveDescription(); + focusedTabProvider.setFocusedTab(null); + + connector.getRpcProxy(FocusAndBlurServerRpc.class).blur(); + } + + // Call this to set it to null and be consistent. + focusBlurManager.removeBlurSchedule(); } } @Override - public void focus() { - tb.getTab(activeTabIndex).focus(); + public void onBlur(BlurEvent event) { + selectionHandler.onBlur(event); } - public void blur() { - tb.getTab(activeTabIndex).blur(); + @Override + public void onFocus(FocusEvent event) { + selectionHandler.onFocus(event); } @Override public void onKeyDown(KeyDownEvent event) { - if (event.getSource() instanceof Tab) { - int keycode = event.getNativeEvent().getKeyCode(); - - if (!event.isAnyModifierKeyDown()) { - if (keycode == getPreviousTabKey()) { - selectPreviousTab(); - event.stopPropagation(); - } else if (keycode == getNextTabKey()) { - selectNextTab(); - event.stopPropagation(); - } else if (keycode == getCloseTabKey()) { - Tab tab = tb.getTab(activeTabIndex); - if (tab.isClosable()) { - tab.onClose(); + selectionHandler.onKeyDown(event); + } + + /* + * The tabs selection handler instance. + */ + private final TabSelectionHandler selectionHandler = new TabSelectionHandler(); + + /* + * Handle the events for selecting the tabs. + */ + private class TabSelectionHandler implements FocusHandler, BlurHandler, + KeyDownHandler, ClickHandler, MouseDownHandler { + + /** For internal use only. May be removed or replaced in the future. */ + // The current visible focused index. + private int focusedTabIndex = 0; + + /** + * Register the tab to the selection handler. + * + * @param tab + * the tab to register. + */ + public void registerTab(Tab tab) { + + // TODO: change VTabsheet.this to this in 7.3 + tab.addBlurHandler(VTabsheet.this); + tab.addFocusHandler(VTabsheet.this); + tab.addKeyDownHandler(VTabsheet.this); + + tab.addClickHandler(this); + tab.addMouseDownHandler(this); + } + + @Override + public void onBlur(final BlurEvent event) { + + getVTooltip().hideTooltip(); + + Object blurSource = event.getSource(); + + if (blurSource instanceof Tab) { + focusBlurManager.blur((Tab) blurSource); + } + } + + @Override + public void onFocus(FocusEvent event) { + + if (event.getSource() instanceof Tab) { + focusBlurManager.focus((Tab) event.getSource()); + } + } + + @Override + public void onClick(ClickEvent event) { + + // IE doesn't trigger focus when click, so we need to make sure + // the previous blur deferred command will get killed. + focusBlurManager.removeBlurSchedule(); + + TabCaption caption = (TabCaption) event.getSource(); + Element targetElement = event.getNativeEvent().getEventTarget() + .cast(); + // the tab should not be focused if the close button was clicked + if (targetElement == caption.getCloseButton()) { + return; + } + + int index = tb.getWidgetIndex(caption.getParent()); + + tb.navigateTab(focusedTabIndex, index); + + focusedTabIndex = index; + + if (!loadTabSheet(index)) { + + // This needs to be called at the end, as the activeTabIndex + // is set in the loadTabSheet. + focus(); + } + } + + @Override + public void onMouseDown(MouseDownEvent event) { + + if (event.getSource() instanceof Tab) { + + // IE doesn't trigger focus when click, so we need to make sure + // the + // next blur deferred command will get killed. + focusBlurManager.cancelNextBlurSchedule(); + } + } + + @Override + public void onKeyDown(KeyDownEvent event) { + if (event.getSource() instanceof Tab) { + int keycode = event.getNativeEvent().getKeyCode(); + + if (!event.isAnyModifierKeyDown()) { + if (keycode == getPreviousTabKey()) { + selectPreviousTab(); + event.stopPropagation(); + + } else if (keycode == getNextTabKey()) { + selectNextTab(); + event.stopPropagation(); + + } else if (keycode == getCloseTabKey()) { + Tab tab = tb.getTab(activeTabIndex); + if (tab.isClosable()) { + tab.onClose(); + } + + } else if (keycode == getSelectTabKey()) { + loadTabSheet(focusedTabIndex); + + // Prevent the page from scrolling when hitting space + // (select key) to select the current tab. + event.preventDefault(); } - } else if (keycode == getSelectTabKey()) { - loadTabSheet(focusedTabIndex); } } } + + /* + * Left arrow key selection. + */ + private void selectPreviousTab() { + int newTabIndex = focusedTabIndex; + // Find the previous visible and enabled tab if any. + do { + newTabIndex--; + } while (newTabIndex >= 0 && !canSelectTab(newTabIndex)); + + if (newTabIndex >= 0) { + keySelectTab(newTabIndex); + } + } + + /* + * Right arrow key selection. + */ + private void selectNextTab() { + int newTabIndex = focusedTabIndex; + // Find the next visible and enabled tab if any. + do { + newTabIndex++; + } while (newTabIndex < getTabCount() && !canSelectTab(newTabIndex)); + + if (newTabIndex < getTabCount()) { + keySelectTab(newTabIndex); + } + } + + /* + * Select the specified tab using left/right key. + */ + private void keySelectTab(int newTabIndex) { + Tab tab = tb.getTab(newTabIndex); + if (tab == null) { + return; + } + + // Focus the tab, otherwise the selected one will loose focus and + // TabSheet will get blurred. + focusTabAtIndex(newTabIndex); + + tb.navigateTab(focusedTabIndex, newTabIndex); + + focusedTabIndex = newTabIndex; + } + + /** + * Focus the specified tab. Make sure to call this only from user + * events, otherwise will break things. + * + * @param tabIndex + * the index of the tab to set. + */ + void focusTabAtIndex(int tabIndex) { + Tab tabToFocus = tb.getTab(tabIndex); + if (tabToFocus != null) { + tabToFocus.focus(); + } + } + } /** @@ -1307,8 +1728,17 @@ public class VTabsheet extends VTabsheetBase implements Focusable, return KeyCodes.KEY_LEFT; } + /** + * Gets the key to activate the selected tab when navigating using + * previous/next (left/right) keys. + * + * @return the key to activate the selected tab. + * + * @see #getNextTabKey() + * @see #getPreviousTabKey() + */ protected int getSelectTabKey() { - return 32; // Space key + return KeyCodes.KEY_SPACE; } /** @@ -1327,66 +1757,32 @@ public class VTabsheet extends VTabsheetBase implements Focusable, return KeyCodes.KEY_DELETE; } - private void selectPreviousTab() { - int newTabIndex = focusedTabIndex; - // Find the previous visible and enabled tab if any. - do { - newTabIndex--; - } while (newTabIndex >= 0 && !canSelectTab(newTabIndex)); - - if (newTabIndex >= 0) { - tb.navigateTab(focusedTabIndex, newTabIndex); - focusedTabIndex = newTabIndex; - - // If this TabSheet already has focus, set the new selected tab - // as focused. - if (focusedTab != null) { - focusedTab = tb.getTab(focusedTabIndex); - focusedTab.focus(); - } - } - } - - private void selectNextTab() { - int newTabIndex = focusedTabIndex; - // Find the next visible and enabled tab if any. - do { - newTabIndex++; - } while (newTabIndex < getTabCount() && !canSelectTab(newTabIndex)); - - if (newTabIndex < getTabCount()) { + private void scrollIntoView(Tab tab) { - tb.navigateTab(focusedTabIndex, newTabIndex); - focusedTabIndex = newTabIndex; + if (!tab.isHiddenOnServer()) { - // If this TabSheet already has focus, set the new selected tab - // as focused. - if (focusedTab != null) { - focusedTab = tb.getTab(focusedTabIndex); - focusedTab.focus(); - } - } - } + // Check for visibility first as clipped tabs to the right are + // always visible. + // On IE8 a tab with false visibility would have the bounds of the + // full TabBar. + if (!tab.isVisible()) { + while (!tab.isVisible()) { + scrollerIndex = tb.scrollLeft(scrollerIndex); + } + updateTabScroller(); - private void scrollIntoView(Tab tab) { - if (!tab.isHiddenOnServer()) { - if (isClipped(tab)) { + } else if (isClipped(tab)) { while (isClipped(tab) && scrollerIndex != -1) { scrollerIndex = tb.scrollRight(scrollerIndex); } updateTabScroller(); - } else if (!tab.isVisible()) { - while (!tab.isVisible()) { - scrollerIndex = tb.scrollLeft(scrollerIndex); - } - updateTabScroller(); } } } /** * Makes tab bar visible. - * + * * @since 7.2 */ public void showTabs() { @@ -1397,7 +1793,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, /** * Makes tab bar invisible. - * + * * @since 7.2 */ public void hideTabs() { diff --git a/client/src/com/vaadin/client/ui/VTextField.java b/client/src/com/vaadin/client/ui/VTextField.java index c517f8fec0..1968c7e0a6 100644 --- a/client/src/com/vaadin/client/ui/VTextField.java +++ b/client/src/com/vaadin/client/ui/VTextField.java @@ -16,6 +16,8 @@ package com.vaadin.client.ui; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; @@ -254,6 +256,48 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler, el.oncut = null; }-*/; + private void onDrop() { + if (focusedTextField == this) { + return; + } + updateText(false); + } + + private void updateText(boolean blurred) { + String text = getText(); + setPrompting(inputPrompt != null && (text == null || text.isEmpty())); + if (prompting) { + setText(isReadOnly() ? "" : inputPrompt); + if (blurred) { + addStyleDependentName(CLASSNAME_PROMPT); + } + } + + valueChange(blurred); + } + + private void scheduleOnDropEvent() { + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + onDrop(); + } + }); + } + + private native void attachDropEventListener(Element el) + /*-{ + var me = this; + el.ondrop = $entry(function() { + me.@com.vaadin.client.ui.VTextField::scheduleOnDropEvent()(); + }); + }-*/; + + private native void detachDropEventListener(Element el) + /*-{ + el.ondrop = null; + }-*/; + @Override protected void onDetach() { super.onDetach(); @@ -263,6 +307,7 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler, } if (BrowserInfo.get().isFirefox()) { removeOnInputListener(getElement()); + detachDropEventListener(getElement()); } } @@ -276,6 +321,9 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler, // Workaround for FF setting input prompt as the value if esc is // pressed while the field is focused and empty (#8051). addOnInputListener(getElement()); + // Workaround for FF updating component's internal value after + // having drag-and-dropped text from another element (#14056) + attachDropEventListener(getElement()); } } @@ -418,14 +466,7 @@ public class VTextField extends TextBoxBase implements Field, ChangeHandler, } removeStyleDependentName(CLASSNAME_FOCUS); focusedTextField = null; - String text = getText(); - setPrompting(inputPrompt != null && (text == null || "".equals(text))); - if (prompting) { - setText(isReadOnly() ? "" : inputPrompt); - addStyleDependentName(CLASSNAME_PROMPT); - } - - valueChange(true); + updateText(true); } private void setPrompting(boolean prompting) { diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java index df24c3b1c7..eae4f6319d 100644 --- a/client/src/com/vaadin/client/ui/VUI.java +++ b/client/src/com/vaadin/client/ui/VUI.java @@ -48,11 +48,12 @@ import com.vaadin.client.Util; import com.vaadin.client.VConsole; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; +import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.ui.UIConstants; /** - * + * */ public class VUI extends SimplePanel implements ResizeHandler, Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable, @@ -62,9 +63,6 @@ public class VUI extends SimplePanel implements ResizeHandler, private static int MONITOR_PARENT_TIMER_INTERVAL = 1000; /** For internal use only. May be removed or replaced in the future. */ - public String theme; - - /** For internal use only. May be removed or replaced in the future. */ public String id; /** For internal use only. May be removed or replaced in the future. */ @@ -319,19 +317,15 @@ public class VUI extends SimplePanel implements ResizeHandler, } } - public String getTheme() { - return theme; - } - /** - * Used to reload host page on theme changes. - * <p> - * For internal use only. May be removed or replaced in the future. + * @return the name of the theme in use by this UI. + * @deprecated as of 7.3. Use {@link UIConnector#getActiveTheme()} instead. */ - public static native void reloadHostPage() - /*-{ - $wnd.location.reload(); - }-*/; + @Deprecated + public String getTheme() { + return ((UIConnector) ConnectorMap.get(connection).getConnector(this)) + .getActiveTheme(); + } /** * Returns true if the body is NOT generated, i.e if someone else has made @@ -530,4 +524,5 @@ public class VUI extends SimplePanel implements ResizeHandler, }); } } + } diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 1cee727bc9..7223e4ac83 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -73,7 +73,7 @@ import com.vaadin.shared.ui.window.WindowRole; /** * "Sub window" component. - * + * * @author Vaadin Ltd */ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, @@ -233,7 +233,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Stores the element that has focus in the application UI when the * window is opened, so it can be restored when the window closes. - * + * * This is currently implemented for the case when one non-modal window * can be open at the same time, and the focus is not changed while the * window is open. @@ -245,6 +245,20 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * state. */ setTabStopEnabled(doTabStop); + + // Fix for #14413. Any pseudo elements inside these elements are not + // visible on initial render unless we shake the DOM. + if (BrowserInfo.get().isIE8()) { + closeBox.getStyle().setDisplay(Display.NONE); + maximizeRestoreBox.getStyle().setDisplay(Display.NONE); + Scheduler.get().scheduleFinally(new Command() { + @Override + public void execute() { + closeBox.getStyle().clearDisplay(); + maximizeRestoreBox.getStyle().clearDisplay(); + } + }); + } } @Override @@ -253,7 +267,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Restores the previously stored focused element. - * + * * When the focus was changed outside the window while the window was * open, the originally stored element is restored. */ @@ -295,7 +309,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Returns true if this window is the topmost VWindow - * + * * @return */ private boolean isActive() { @@ -437,7 +451,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * is prevented. * <p> * This message is not visible on the screen. - * + * * @param topMessage * String provided when the user navigates with Shift-Tab keys to * the top of the window @@ -452,7 +466,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * key is prevented. * <p> * This message is not visible on the screen. - * + * * @param bottomMessage * String provided when the user navigates with the Tab key to * the bottom of the window @@ -465,7 +479,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the message that is provided to users of assistive devices when the * user reaches the top of the window when leaving a window with the tab key * is prevented. - * + * * @return the top message */ public String getTabStopTopAssistiveText() { @@ -476,7 +490,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the message that is provided to users of assistive devices when the * user reaches the bottom of the window when leaving a window with the tab * key is prevented. - * + * * @return the bottom message */ public String getTabStopBottomAssistiveText() { @@ -554,41 +568,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /* * Shake up the DOM a bit to make the window shed unnecessary - * scrollbars and resize correctly afterwards. This resulting code - * took over a week to summon forth, and involved some pretty hairy - * black magic. Don't touch it unless you know what you're doing! - * Fixes ticket #11994 + * scrollbars and resize correctly afterwards. The version fixing + * ticket #11994 which was changing the size to 110% was replaced + * with this due to ticket #12943 */ - Scheduler.get().scheduleFinally(new ScheduledCommand() { - @Override - public void execute() { - final com.google.gwt.dom.client.Element scrollable = contents - .getFirstChildElement(); - - // Adjusting the width or height may change the scroll - // position, so store the current position - int horizontalScrollPosition = scrollable.getScrollLeft(); - int verticalScrollPosition = scrollable.getScrollTop(); - - final String oldWidth = scrollable.getStyle().getWidth(); - final String oldHeight = scrollable.getStyle().getHeight(); - - scrollable.getStyle().setWidth(110, Unit.PCT); - scrollable.getOffsetWidth(); - scrollable.getStyle().setProperty("width", oldWidth); - - scrollable.getStyle().setHeight(110, Unit.PCT); - scrollable.getOffsetHeight(); - scrollable.getStyle().setProperty("height", oldHeight); - - // Restore the scroll position - scrollable.setScrollLeft(horizontalScrollPosition); - scrollable.setScrollTop(verticalScrollPosition); - - updateContentsSize(); - positionOrSizeUpdated(); - } - }); + Util.runWebkitOverflowAutoFix(contents.getFirstChildElement()); } } @@ -616,7 +600,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Sets the closable state of the window. Additionally hides/shows the close * button according to the new state. - * + * * @param closable * true if the window can be closed by the user */ @@ -638,7 +622,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Returns the closable state of the sub window. If the sub window is * closable a decoration (typically an X) is shown to the user. By clicking * on the X the user can close the window. - * + * * @return true if the sub window is closable */ protected boolean isClosable() { @@ -670,7 +654,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * correctly if clicking on the "close" button in the window header but * closing the window from a button for example in the window will fail. * Symptom described in #10776 - * + * * The problematic part is that for the focus to be returned correctly * an input element needs to be focused in the root panel. Focusing some * other element apparently won't work. @@ -902,7 +886,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Setter for the text for assistive devices the window caption is prefixed * with. - * + * * @param assistivePrefix * the assistivePrefix to set */ @@ -913,7 +897,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Getter for the text for assistive devices the window caption is prefixed * with. - * + * * @return the assistivePrefix */ public String getAssistivePrefix() { @@ -923,7 +907,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Setter for the text for assistive devices the window caption is postfixed * with. - * + * * @param assistivePostfix * the assistivePostfix to set */ @@ -934,7 +918,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Getter for the text for assistive devices the window caption is postfixed * with. - * + * * @return the assistivePostfix */ public String getAssistivePostfix() { @@ -1086,14 +1070,14 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * TODO check if we need to support this with touch based devices. - * + * * Checks if the cursor was inside the browser content area when the event * happened. - * + * * @param event * The event to be checked * @return true, if the cursor is inside the browser content area - * + * * false, otherwise */ private boolean cursorInsideBrowserContentArea(Event event) { @@ -1382,7 +1366,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * assistive devices when it is opened. * <p> * When the provided array is empty, an existing description is removed. - * + * * @param connectors * with the connectors of the widgets to use as description */ @@ -1420,7 +1404,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * Gets the connectors that are used as assistive description. Text * contained in these connectors will be read by assistive devices when the * window is opened. - * + * * @return list of previously set connectors */ public List<Connector> getAssistiveDescription() { @@ -1429,19 +1413,19 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Sets the WAI-ARIA role the window. - * + * * This role defines how an assistive device handles a window. Available * roles are alertdialog and dialog (@see <a * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles * Model</a>). - * + * * The default role is dialog. - * + * * @param role * WAI-ARIA role to set for the window */ public void setWaiAriaRole(WindowRole role) { - if ("alertdialog".equals(role)) { + if (role == WindowRole.ALERTDIALOG) { Roles.getAlertdialogRole().set(getElement()); } else { Roles.getDialogRole().set(getElement()); @@ -1455,7 +1439,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, * The value of the parameter doTabStop is stored and used for non-modal * windows. For modal windows, the handlers are always registered, while * preserving the stored value. - * + * * @param doTabStop * true to prevent leaving the window, false to allow leaving the * window for non modal windows @@ -1472,9 +1456,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, /** * Adds a Handler for when user moves the window. - * + * * @since 7.1.9 - * + * * @return {@link HandlerRegistration} used to remove the handler */ public HandlerRegistration addMoveHandler(WindowMoveHandler handler) { diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 78505d034c..8feb349a9e 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -28,7 +28,6 @@ import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.ui.VFilterSelect; import com.vaadin.client.ui.VFilterSelect.FilterSelectSuggestion; -import com.vaadin.client.ui.menubar.MenuItem; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.combobox.ComboBoxConstants; import com.vaadin.shared.ui.combobox.ComboBoxState; @@ -157,7 +156,15 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } // handle selection (null or a single value) - if (uidl.hasVariable("selected")) { + if (uidl.hasVariable("selected") + + // In case we're switching page no need to update the selection as the + // selection process didn't finish. + // && getWidget().selectPopupItemWhenResponseIsReceived == + // VFilterSelect.Select.NONE + // + ) { + String[] selectedKeys = uidl.getStringArrayVariable("selected"); if (selectedKeys.length > 0) { performSelection(selectedKeys[0]); @@ -169,12 +176,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements if ((getWidget().waitingForFilteringResponse && getWidget().lastFilter .toLowerCase().equals(uidl.getStringVariable("filter"))) || popupOpenAndCleared) { + getWidget().suggestionPopup.showSuggestions( getWidget().currentSuggestions, getWidget().currentPage, getWidget().totalMatches); + getWidget().waitingForFilteringResponse = false; + if (!getWidget().popupOpenerClicked && getWidget().selectPopupItemWhenResponseIsReceived != VFilterSelect.Select.NONE) { + // we're paging w/ arrows Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override @@ -222,26 +233,16 @@ public class ComboBoxConnector extends AbstractFieldConnector implements */ private void navigateItemAfterPageChange() { if (getWidget().selectPopupItemWhenResponseIsReceived == VFilterSelect.Select.LAST) { - getWidget().suggestionPopup.menu.selectLastItem(); + getWidget().suggestionPopup.selectLastItem(); } else { - getWidget().suggestionPopup.menu.selectFirstItem(); + getWidget().suggestionPopup.selectFirstItem(); } - // This is used for paging so we update the keyboard selection - // variable as well. - MenuItem activeMenuItem = getWidget().suggestionPopup.menu - .getSelectedItem(); - getWidget().suggestionPopup.menu - .setKeyboardSelectedItem(activeMenuItem); - - // Update text field to contain the correct text - getWidget().setTextboxText(activeMenuItem.getText()); - getWidget().tb.setSelectionRange( - getWidget().lastFilter.length(), - activeMenuItem.getText().length() - - getWidget().lastFilter.length()); - - getWidget().selectPopupItemWhenResponseIsReceived = VFilterSelect.Select.NONE; // reset + // If you're in between 2 requests both changing the page back and + // forth, you don't want this here, instead you need it before any + // other request. + // getWidget().selectPopupItemWhenResponseIsReceived = + // VFilterSelect.Select.NONE; // reset } private void performSelection(String selectedKey) { diff --git a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java index a349eb2993..6f059a7c16 100644 --- a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java +++ b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java @@ -87,15 +87,17 @@ public class PopupDateFieldConnector extends TextualDateConnector { .isShowISOWeekNumbers()); if (getWidget().calendar.getResolution() != getWidget() .getCurrentResolution()) { + boolean hasSelectedDate = false; getWidget().calendar.setResolution(getWidget() .getCurrentResolution()); if (getWidget().calendar.getDate() != null && getWidget().getCurrentDate() != null) { + hasSelectedDate = true; getWidget().calendar.setDate((Date) getWidget() .getCurrentDate().clone()); - // force re-render when changing resolution only - getWidget().calendar.renderCalendar(); } + // force re-render when changing resolution only + getWidget().calendar.renderCalendar(hasSelectedDate); } // Force re-render of calendar if locale has changed (#12153) diff --git a/client/src/com/vaadin/client/ui/dd/DDUtil.java b/client/src/com/vaadin/client/ui/dd/DDUtil.java index dfdafe1352..77de1f9b1a 100644 --- a/client/src/com/vaadin/client/ui/dd/DDUtil.java +++ b/client/src/com/vaadin/client/ui/dd/DDUtil.java @@ -58,8 +58,7 @@ public class DDUtil { } public static HorizontalDropLocation getHorizontalDropLocation( - Element element, NativeEvent event, - double leftRightRatio) { + Element element, NativeEvent event, double leftRightRatio) { int clientX = Util.getTouchOrMouseClientX(event); // Event coordinates are relative to the viewport, element absolute diff --git a/client/src/com/vaadin/client/ui/dd/DragImageModifier.java b/client/src/com/vaadin/client/ui/dd/DragImageModifier.java index f08c082a70..45ab5d9bb3 100644 --- a/client/src/com/vaadin/client/ui/dd/DragImageModifier.java +++ b/client/src/com/vaadin/client/ui/dd/DragImageModifier.java @@ -20,7 +20,8 @@ import com.google.gwt.dom.client.Element; /** * Interface implemented by widgets if the drag image used for drag'n'drop * requires additional initialization/configuration. The method - * {@link #modifyDragImage(Element)} is called for each element in the automatically generated drag image. + * {@link #modifyDragImage(Element)} is called for each element in the + * automatically generated drag image. * * @since 7.2 * @author Vaadin Ltd diff --git a/client/src/com/vaadin/client/ui/menubar/MenuBar.java b/client/src/com/vaadin/client/ui/menubar/MenuBar.java index b00665e766..726defafd5 100644 --- a/client/src/com/vaadin/client/ui/menubar/MenuBar.java +++ b/client/src/com/vaadin/client/ui/menubar/MenuBar.java @@ -38,6 +38,7 @@ import java.util.List; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; @@ -74,6 +75,9 @@ import com.vaadin.client.ui.VOverlay; public class MenuBar extends Widget implements PopupListener { private final Element body; + private final Element table; + private final Element outer; + private final ArrayList<MenuItem> items = new ArrayList<MenuItem>(); private MenuBar parentMenu; private PopupPanel popup; @@ -98,7 +102,7 @@ public class MenuBar extends Widget implements PopupListener { public MenuBar(boolean vertical) { super(); - final Element table = DOM.createTable(); + table = DOM.createTable(); body = DOM.createTBody(); DOM.appendChild(table, body); @@ -109,7 +113,7 @@ public class MenuBar extends Widget implements PopupListener { this.vertical = vertical; - final Element outer = DOM.createDiv(); + outer = DOM.createDiv(); DOM.appendChild(outer, table); setElement(outer); @@ -324,6 +328,37 @@ public class MenuBar extends Widget implements PopupListener { return selectedItem; } + /** + * Gets the first item from the menu or null if no items. + * + * @since + * @return the first item from the menu or null if no items. + */ + public MenuItem getFirstItem() { + return items != null && items.size() > 0 ? items.get(0) : null; + } + + /** + * Gest the last item from the menu or null if no items. + * + * @since + * @return the last item from the menu or null if no items. + */ + public MenuItem getLastItem() { + return items != null && items.size() > 0 ? items.get(items.size() - 1) + : null; + } + + /** + * Gets the index of the selected item. + * + * @since + * @return the index of the selected item. + */ + public int getSelectedIndex() { + return items != null ? items.indexOf(getSelectedItem()) : -1; + } + @Override protected void onDetach() { // When the menu is detached, make sure to close all of its children. @@ -468,6 +503,7 @@ public class MenuBar extends Widget implements PopupListener { public void selectItem(MenuItem item) { if (item == selectedItem) { + scrollItemIntoView(item); return; } @@ -480,6 +516,74 @@ public class MenuBar extends Widget implements PopupListener { } selectedItem = item; + + scrollItemIntoView(item); + } + + /* + * Scroll the specified item into view. + */ + private void scrollItemIntoView(MenuItem item) { + if (item != null) { + item.getElement().scrollIntoView(); + } + } + + /** + * Scroll the selected item into view. + * + * @since + */ + public void scrollSelectionIntoView() { + scrollItemIntoView(selectedItem); + } + + /** + * Sets the menu scroll enabled or disabled. + * + * @since + * @param enabled + * the enabled state of the scroll. + */ + public void setScrollEnabled(boolean enabled) { + if (enabled) { + if (vertical) { + outer.getStyle().setOverflowY(Overflow.AUTO); + } else { + outer.getStyle().setOverflowX(Overflow.AUTO); + } + + } else { + if (vertical) { + outer.getStyle().clearOverflowY(); + } else { + outer.getStyle().clearOverflowX(); + } + } + } + + /** + * Gets whether the scroll is activate for this menu. + * + * @since + * @return true if the scroll is active, otherwise false. + */ + public boolean isScrollActive() { + // Element element = getElement(); + // return element.getOffsetHeight() > DOM.getChild(element, 0) + // .getOffsetHeight(); + int outerHeight = outer.getOffsetHeight(); + int tableHeight = table.getOffsetHeight(); + return outerHeight < tableHeight; + } + + /** + * Gets the preferred height of the menu. + * + * @since + */ + protected int getPreferredHeight() { + return table.getOffsetHeight(); } /** diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java index bea49e5f27..56b35cce56 100644 --- a/client/src/com/vaadin/client/ui/table/TableConnector.java +++ b/client/src/com/vaadin/client/ui/table/TableConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -21,7 +21,6 @@ import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Position; -import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; @@ -55,6 +54,17 @@ public class TableConnector extends AbstractHasComponentsConnector implements /* * (non-Javadoc) * + * @see com.vaadin.client.ui.AbstractComponentConnector#onUnregister() + */ + @Override + public void onUnregister() { + super.onUnregister(); + getWidget().onUnregister(); + } + + /* + * (non-Javadoc) + * * @see com.vaadin.client.Paintable#updateFromUIDL(com.vaadin.client.UIDL, * com.vaadin.client.ApplicationConnection) */ @@ -111,7 +121,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements int previousTotalRows = getWidget().totalRows; getWidget().updateTotalRows(uidl); - boolean totalRowsChanged = (getWidget().totalRows != previousTotalRows); + boolean totalRowsHaveChanged = (getWidget().totalRows != previousTotalRows); getWidget().updateDragMode(uidl); @@ -189,7 +199,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements if (getWidget().headerChangedDuringUpdate) { getWidget().triggerLazyColumnAdjustment(true); } else if (!getWidget().isScrollPositionVisible() - || totalRowsChanged + || totalRowsHaveChanged || getWidget().lastRenderedHeight != getWidget().scrollBody .getOffsetHeight()) { // webkits may still bug with their disturbing scrollbar @@ -199,13 +209,8 @@ public class TableConnector extends AbstractHasComponentsConnector implements // by changing overflows as the length of the contents // *shouldn't* have changed (unless the number of rows // or the height of the widget has also changed) - Scheduler.get().scheduleDeferred(new Command() { - @Override - public void execute() { - Util.runWebkitOverflowAutoFix(getWidget().scrollBodyPanel - .getElement()); - } - }); + Util.runWebkitOverflowAutoFixDeferred(getWidget().scrollBodyPanel + .getElement()); } } else { getWidget().initializeRows(uidl, rowData); @@ -379,7 +384,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements /** * Shows a saved row context menu if the row for the context menu is still * visible. Does nothing if a context menu has not been saved. - * + * * @param savedContextMenu */ public void showSavedContextMenu(ContextMenuDetails savedContextMenu) { diff --git a/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java b/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java index e406ff5459..e9dc3e1dd7 100644 --- a/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java +++ b/client/src/com/vaadin/client/ui/textarea/TextAreaConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -16,6 +16,10 @@ package com.vaadin.client.ui.textarea; +import com.google.gwt.dom.client.Element; +import com.google.gwt.event.dom.client.MouseUpEvent; +import com.google.gwt.event.dom.client.MouseUpHandler; +import com.vaadin.client.Util.CssSize; import com.vaadin.client.ui.VTextArea; import com.vaadin.client.ui.textfield.TextFieldConnector; import com.vaadin.shared.ui.Connect; @@ -34,4 +38,54 @@ public class TextAreaConnector extends TextFieldConnector { public VTextArea getWidget() { return (VTextArea) super.getWidget(); } + + @Override + protected void init() { + super.init(); + + getWidget().addMouseUpHandler(new ResizeMouseUpHandler()); + } + + /* + * Workaround to handle the resize on the mouse up. + */ + private class ResizeMouseUpHandler implements MouseUpHandler { + + @Override + public void onMouseUp(MouseUpEvent event) { + Element element = getWidget().getElement(); + + updateSize(element.getStyle().getHeight(), getState().height, + "height"); + updateSize(element.getStyle().getWidth(), getState().width, "width"); + } + + /* + * Update the specified size on the server. + */ + private void updateSize(String sizeText, String stateSizeText, + String sizeType) { + + CssSize stateSize = CssSize.fromString(stateSizeText); + CssSize newSize = CssSize.fromString(sizeText); + + if (stateSize == null && newSize == null) { + return; + + } else if (newSize == null) { + sizeText = ""; + + // Else, if the current stateSize is null, just go ahead and set + // the newSize, so no check on stateSize is needed. + + } else if (stateSize != null && stateSize.equals(newSize)) { + return; + } + + getConnection().updateVariable(getConnectorId(), sizeType, + sizeText, false); + } + + } + } diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 1d2a49cbd1..c88fd23eca 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -18,6 +18,7 @@ package com.vaadin.client.ui.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.logging.Logger; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; @@ -26,8 +27,10 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.HeadElement; import com.google.gwt.dom.client.LinkElement; import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.NodeList; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.StyleElement; import com.google.gwt.dom.client.StyleInjector; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; @@ -51,12 +54,17 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; import com.vaadin.client.Focusable; import com.vaadin.client.Paintable; +import com.vaadin.client.ResourceLoader; +import com.vaadin.client.ResourceLoader.ResourceLoadEvent; +import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.ServerConnector; import com.vaadin.client.UIDL; import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; +import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.client.ui.AbstractConnector; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; import com.vaadin.client.ui.ShortcutActionHandler; @@ -66,6 +74,7 @@ import com.vaadin.client.ui.VUI; import com.vaadin.client.ui.layout.MayScrollChildren; import com.vaadin.client.ui.window.WindowConnector; import com.vaadin.server.Page.Styles; +import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.communication.MethodInvocation; import com.vaadin.shared.ui.ComponentStateUtil; @@ -80,6 +89,7 @@ import com.vaadin.shared.ui.ui.UIClientRpc; import com.vaadin.shared.ui.ui.UIConstants; import com.vaadin.shared.ui.ui.UIServerRpc; import com.vaadin.shared.ui.ui.UIState; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.UI; @Connect(value = UI.class, loadStyle = LoadStyle.EAGER) @@ -88,6 +98,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private HandlerRegistration childStateChangeHandlerRegistration; + private String activeTheme = null; + private final StateChangeHandler childStateChangeHandler = new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { @@ -197,14 +209,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getWidget().immediate = getState().immediate; getWidget().resizeLazy = uidl.hasAttribute(UIConstants.RESIZE_LAZY); - String newTheme = uidl.getStringAttribute("theme"); - if (getWidget().theme != null && !newTheme.equals(getWidget().theme)) { - // Complete page refresh is needed due css can affect layout - // calculations etc - getWidget().reloadHostPage(); - } else { - getWidget().theme = newTheme; - } // this also implicitly removes old styles String styles = ""; styles += getWidget().getStylePrimaryName() + " "; @@ -405,9 +409,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector */ private void injectCSS(UIDL uidl) { - final HeadElement head = HeadElement.as(Document.get() - .getElementsByTagName(HeadElement.TAG).getItem(0)); - /* * Search the UIDL stream for CSS resources and strings to be injected. */ @@ -424,8 +425,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector link.setRel("stylesheet"); link.setHref(url); link.setType("text/css"); - head.appendChild(link); - + getHead().appendChild(link); // Check if we have CSS string to inject } else if (cssInjectionsUidl.getTag().equals("css-string")) { for (Iterator<?> it2 = cssInjectionsUidl.getChildIterator(); it2 @@ -437,8 +437,54 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } + /** + * Internal helper to get the <head> tag of the page + * + * @since 7.3 + * @return the head element + */ + private HeadElement getHead() { + return HeadElement.as(Document.get() + .getElementsByTagName(HeadElement.TAG).getItem(0)); + } + + /** + * Internal helper for removing any stylesheet with the given URL + * + * @since 7.3 + * @param url + * the url to match with existing stylesheets + */ + private void removeStylesheet(String url) { + NodeList<Element> linkTags = getHead().getElementsByTagName( + LinkElement.TAG); + for (int i = 0; i < linkTags.getLength(); i++) { + LinkElement link = LinkElement.as(linkTags.getItem(i)); + if (!"stylesheet".equals(link.getRel())) { + continue; + } + if (!"text/css".equals(link.getType())) { + continue; + } + if (url.equals(link.getHref())) { + getHead().removeChild(link); + } + } + } + public void init(String rootPanelId, ApplicationConnection applicationConnection) { + // Create a style tag for style injections so they don't end up in + // the theme tag in IE8-IE10 (we don't want to wipe them out if we + // change theme). + // StyleInjectorImplIE always injects to the last style tag on the page. + if (BrowserInfo.get().isIE() + && BrowserInfo.get().getBrowserMajorVersion() < 11) { + StyleElement style = Document.get().createStyleElement(); + style.setType("text/css"); + getHead().appendChild(style); + } + DOM.sinkEvents(getWidget().getElement(), Event.ONKEYDOWN | Event.ONSCROLL); @@ -448,9 +494,7 @@ public class UIConnector extends AbstractSingleComponentContainerConnector // the user root.getElement().setInnerHTML(""); - String themeName = applicationConnection.getConfiguration() - .getThemeName(); - root.addStyleName(themeName); + activeTheme = applicationConnection.getConfiguration().getThemeName(); root.add(getWidget()); @@ -760,4 +804,229 @@ public class UIConnector extends AbstractSingleComponentContainerConnector getRpcProxy(DebugWindowServerRpc.class).showServerDebugInfo( serverConnector); } + + @OnStateChange("theme") + void onThemeChange() { + final String oldTheme = activeTheme; + final String newTheme = getState().theme; + final String oldThemeUrl = getThemeUrl(oldTheme); + final String newThemeUrl = getThemeUrl(newTheme); + + if (SharedUtil.equals(oldTheme, newTheme)) { + // This should only happen on the initial load when activeTheme has + // been updated in init. + + if (newTheme == null) { + return; + } + + // For the embedded case we cannot be 100% sure that the theme has + // been loaded and that the style names have been set. + + if (findStylesheetTag(oldThemeUrl) == null) { + // If there is no style tag, load it the normal way (the class + // name will be added when theme has been loaded) + replaceTheme(null, newTheme, null, newThemeUrl); + } else if (!getWidget().getParent().getElement() + .hasClassName(newTheme)) { + // If only the class name is missing, add that + activateTheme(newTheme); + } + return; + } + + getLogger().info("Changing theme from " + oldTheme + " to " + newTheme); + replaceTheme(oldTheme, newTheme, oldThemeUrl, newThemeUrl); + } + + /** + * Loads the new theme and removes references to the old theme + * + * @param oldTheme + * The name of the old theme + * @param newTheme + * The name of the new theme + * @param oldThemeUrl + * The url of the old theme + * @param newThemeUrl + * The url of the new theme + */ + private void replaceTheme(final String oldTheme, final String newTheme, + String oldThemeUrl, final String newThemeUrl) { + + LinkElement tagToReplace = null; + + if (oldTheme != null) { + tagToReplace = findStylesheetTag(oldThemeUrl); + + if (tagToReplace == null) { + getLogger() + .warning( + "Did not find the link tag for the old theme (" + + oldThemeUrl + + "), adding a new stylesheet for the new theme (" + + newThemeUrl + ")"); + } + } + + if (newTheme != null) { + loadTheme(newTheme, newThemeUrl, tagToReplace); + } else { + if (tagToReplace != null) { + tagToReplace.getParentElement().removeChild(tagToReplace); + } + + activateTheme(null); + } + + } + + /** + * Finds a link tag for a style sheet with the given URL + * + * @since 7.3 + * @param url + * the URL of the style sheet + * @return the link tag or null if no matching link tag was found + */ + private LinkElement findStylesheetTag(String url) { + NodeList<Element> linkTags = getHead().getElementsByTagName( + LinkElement.TAG); + for (int i = 0; i < linkTags.getLength(); i++) { + final LinkElement link = LinkElement.as(linkTags.getItem(i)); + if ("stylesheet".equals(link.getRel()) + && "text/css".equals(link.getType()) + && url.equals(link.getHref())) { + return link; + } + } + return null; + } + + /** + * Loads the given theme and replaces the given link element with the new + * theme link element. + * + * @param newTheme + * The name of the new theme + * @param newThemeUrl + * The url of the new theme + * @param tagToReplace + * The link element to replace. If null, then the new link + * element is added at the end. + */ + private void loadTheme(final String newTheme, final String newThemeUrl, + final LinkElement tagToReplace) { + LinkElement newThemeLinkElement = Document.get().createLinkElement(); + newThemeLinkElement.setRel("stylesheet"); + newThemeLinkElement.setType("text/css"); + newThemeLinkElement.setHref(newThemeUrl); + ResourceLoader.addOnloadHandler(newThemeLinkElement, + new ResourceLoadListener() { + + @Override + public void onLoad(ResourceLoadEvent event) { + getLogger().info( + "Loading of " + newTheme + " from " + + newThemeUrl + " completed"); + + if (tagToReplace != null) { + tagToReplace.getParentElement().removeChild( + tagToReplace); + } + activateTheme(newTheme); + } + + @Override + public void onError(ResourceLoadEvent event) { + getLogger().warning( + "Could not load theme from " + + getThemeUrl(newTheme)); + } + }, null); + + if (tagToReplace != null) { + getHead().insertBefore(newThemeLinkElement, tagToReplace); + } else { + getHead().appendChild(newThemeLinkElement); + } + } + + /** + * Activates the new theme. Assumes the theme has been loaded and taken into + * use in the browser. + * + * @since 7.3 + * @param newTheme + */ + private void activateTheme(String newTheme) { + if (activeTheme != null) { + getWidget().getParent().removeStyleName(activeTheme); + VOverlay.getOverlayContainer(getConnection()).removeClassName( + activeTheme); + } + + activeTheme = newTheme; + + if (newTheme != null) { + getWidget().getParent().addStyleName(newTheme); + VOverlay.getOverlayContainer(getConnection()).addClassName( + activeTheme); + } + + forceStateChangeRecursively(UIConnector.this); + getLayoutManager().forceLayout(); + } + + /** + * Force a full recursive recheck of every connector's state variables. + * + * @see #forceStateChange() + * + * @since 7.3 + */ + protected static void forceStateChangeRecursively( + AbstractConnector connector) { + connector.forceStateChange(); + + for (ServerConnector child : connector.getChildren()) { + if (child instanceof AbstractConnector) { + forceStateChangeRecursively((AbstractConnector) child); + } else { + getLogger().warning( + "Could not force state change for unknown connector type: " + + child.getClass().getName()); + } + } + + } + + /** + * Internal helper to get the theme URL for a given theme + * + * @since 7.3 + * @param theme + * the name of the theme + * @return The URL the theme can be loaded from + */ + private String getThemeUrl(String theme) { + return getConnection().translateVaadinUri( + ApplicationConstants.VAADIN_PROTOCOL_PREFIX + "themes/" + theme + + "/styles" + ".css"); + } + + /** + * Returns the name of the theme currently in used by the UI + * + * @since 7.3 + * @return the theme name used by this UI + */ + public String getActiveTheme() { + return activeTheme; + } + + private static Logger getLogger() { + return Logger.getLogger(UIConnector.class.getName()); + } + } diff --git a/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java b/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java index 5b428574e2..e38054e3e4 100644 --- a/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java +++ b/client/tests/src/com/vaadin/client/TestVBrowserDetailsUserAgentParser.java @@ -28,6 +28,7 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase { private static final String IE10_WINDOWS_8 = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"; private static final String IE11_WINDOWS_7 = "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; rv:11.0) like Gecko"; + private static final String IE11_WINDOWS_PHONE_8_1_UPDATE = "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920) Like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537"; // "Version/" was added in 10.00 private static final String OPERA964_WINDOWS = "Opera/9.64(Windows NT 5.1; U; en) Presto/2.1.1"; @@ -396,6 +397,16 @@ public class TestVBrowserDetailsUserAgentParser extends TestCase { assertWindows(bd); } + public void testIE11WindowsPhone81Update() { + VBrowserDetails bd = new VBrowserDetails(IE11_WINDOWS_PHONE_8_1_UPDATE); + assertTrident(bd); + assertEngineVersion(bd, 7); + assertIE(bd); + assertBrowserMajorVersion(bd, 11); + assertBrowserMinorVersion(bd, 0); + assertWindows(bd); + } + /* * Helper methods below */ diff --git a/push/build.xml b/push/build.xml index dfc8d03156..dee5820efb 100644 --- a/push/build.xml +++ b/push/build.xml @@ -16,7 +16,7 @@ <property name="vaadinPush.debug.js" location="${result.dir}/js/VAADIN/vaadinPush.debug.js" /> <!-- Keep the version number in sync with ivy.xml, server/src/com/vaadin/server/Constants.java --> - <property name="atmosphere.runtime.version" value="2.1.2.vaadin2" /> + <property name="atmosphere.runtime.version" value="2.1.2.vaadin3" /> <property name="jquery.js" location="lib/jquery/jquery-1.11.0.js" /> <path id="classpath.compile.custom" /> diff --git a/push/ivy.xml b/push/ivy.xml index 1b98969fca..d3b4944353 100644 --- a/push/ivy.xml +++ b/push/ivy.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ivy-module [ <!-- Keep the version number in sync with build.xml --> - <!ENTITY atmosphere.runtime.version "2.1.2.vaadin2"> + <!ENTITY atmosphere.runtime.version "2.1.2.vaadin3"> <!ENTITY atmosphere.js.version "2.1.5.vaadin4"> ]> diff --git a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java index eafd3573bc..0bfec33957 100644 --- a/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java +++ b/server/src/com/vaadin/data/util/ContainerHierarchicalWrapper.java @@ -701,7 +701,9 @@ public class ContainerHierarchicalWrapper implements Container.Hierarchical, */ @Override public int size() { - return container.size(); + int size = container.size(); + assert size >= 0; + return size; } /* diff --git a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java index 483753da88..4bb4e4c1b2 100644 --- a/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java +++ b/server/src/com/vaadin/data/util/ContainerOrderedWrapper.java @@ -494,6 +494,7 @@ public class ContainerOrderedWrapper implements Container.Ordered, @Override public int size() { int newSize = container.size(); + assert newSize >= 0; if (lastKnownSize != -1 && newSize != lastKnownSize && !(container instanceof Container.ItemSetChangeNotifier)) { // Update the internal cache when the size of the container changes diff --git a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java index acf6a870c6..410eea3c01 100644 --- a/server/src/com/vaadin/server/AbstractJavaScriptExtension.java +++ b/server/src/com/vaadin/server/AbstractJavaScriptExtension.java @@ -103,6 +103,8 @@ import com.vaadin.ui.JavaScriptFunction; * <li>The primitive Java boolean and the boxed Boolean are represented by * JavaScript booleans.</li> * <li>Java Strings are represented by JavaScript strings.</li> + * <li>Java Dates are represented by JavaScript numbers containing the timestamp + * </li> * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> * <li>Map<String, ?> in Java is represented by JavaScript object with fields * corresponding to the map keys.</li> diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 3c75764075..73bafcca25 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -45,10 +45,10 @@ import com.vaadin.shared.communication.PushMode; import com.vaadin.ui.UI; /** - * + * * @author Vaadin Ltd * @since 7.0.0 - * + * * @deprecated As of 7.0. Will likely change or be removed in a future version */ @Deprecated @@ -336,9 +336,9 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { * Override this method if you want to add some custom html around around * the div element into which the actual Vaadin application will be * rendered. - * + * * @param context - * + * * @throws IOException * @throws JSONException */ @@ -397,7 +397,8 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { "type", "text/javascript").attr("src", pushJS)); } - String bootstrapLocation = vaadinLocation + "vaadinBootstrap.js"; + String bootstrapLocation = vaadinLocation + + ApplicationConstants.VAADIN_BOOTSTRAP_JS; fragmentNodes.add(new Element(Tag.valueOf("script"), "").attr("type", "text/javascript").attr("src", bootstrapLocation)); Element mainScriptTag = new Element(Tag.valueOf("script"), "").attr( @@ -543,13 +544,13 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Get the URI for the application theme. - * + * * A portal-wide default theme is fetched from the portal shared resource * directory (if any), other themes from the portlet. - * + * * @param context * @param themeName - * + * * @return */ public String getThemeUri(BootstrapContext context, String themeName) { @@ -562,7 +563,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Override if required - * + * * @param context * @return */ @@ -574,7 +575,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { /** * Don not override. - * + * * @param context * @return */ diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index 34c9b5b767..08b5b70f50 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -67,7 +67,7 @@ public interface Constants { // Keep the version number in sync with push/build.xml and other locations // listed in that file - static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin2"; + static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.2.vaadin3"; static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n" + "=================================================================\n" diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/com/vaadin/server/FontAwesome.java index c99f42fac1..f226e0c320 100644 --- a/server/src/com/vaadin/server/FontAwesome.java +++ b/server/src/com/vaadin/server/FontAwesome.java @@ -26,7 +26,7 @@ package com.vaadin.server; * icon font - either to get other icons, or to minimize the size of the font. * </p> * <p> - * The Font Awesome version currently included is 4.0.3. + * The Font Awesome version currently included is 4.1.0. * </p> * * @since 7.2 @@ -34,375 +34,509 @@ package com.vaadin.server; * @see http://fortawesome.github.io/Font-Awesome/ */ public enum FontAwesome implements FontIcon { - GLASS(0XF000), // - MUSIC(0XF001), // - SEARCH(0XF002), // - ENVELOPE_O(0XF003), // - HEART(0XF004), // - STAR(0XF005), // - STAR_O(0XF006), // - USER(0XF007), // - FILM(0XF008), // - TH_LARGE(0XF009), // - TH(0XF00A), // - TH_LIST(0XF00B), // - CHECK(0XF00C), // - TIMES(0XF00D), // - SEARCH_PLUS(0XF00E), // - SEARCH_MINUS(0XF010), // - POWER_OFF(0XF011), // - SIGNAL(0XF012), // - COG(0XF013), // - TRASH_O(0XF014), // - HOME(0XF015), // - FILE_O(0XF016), // - CLOCK_O(0XF017), // - ROAD(0XF018), // - DOWNLOAD(0XF019), // + ADJUST(0XF042), // + ADN(0XF170), // + ALIGN_CENTER(0XF037), // + ALIGN_JUSTIFY(0XF039), // + ALIGN_LEFT(0XF036), // + ALIGN_RIGHT(0XF038), // + AMBULANCE(0XF0F9), // + ANCHOR(0XF13D), // + ANDROID(0XF17B), // + ANGLE_DOUBLE_DOWN(0XF103), // + ANGLE_DOUBLE_LEFT(0XF100), // + ANGLE_DOUBLE_RIGHT(0XF101), // + ANGLE_DOUBLE_UP(0XF102), // + ANGLE_DOWN(0XF107), // + ANGLE_LEFT(0XF104), // + ANGLE_RIGHT(0XF105), // + ANGLE_UP(0XF106), // + APPLE(0XF179), // + ARCHIVE(0XF187), // + ARROW_CIRCLE_DOWN(0XF0AB), // + ARROW_CIRCLE_LEFT(0XF0A8), // ARROW_CIRCLE_O_DOWN(0XF01A), // + ARROW_CIRCLE_O_LEFT(0XF190), // + ARROW_CIRCLE_O_RIGHT(0XF18E), // ARROW_CIRCLE_O_UP(0XF01B), // - INBOX(0XF01C), // - PLAY_CIRCLE_O(0XF01D), // - REPEAT(0XF01E), // - REFRESH(0XF021), // - LIST_ALT(0XF022), // - LOCK(0XF023), // - FLAG(0XF024), // - HEADPHONES(0XF025), // - VOLUME_OFF(0XF026), // - VOLUME_DOWN(0XF027), // - VOLUME_UP(0XF028), // - QRCODE(0XF029), // + ARROW_CIRCLE_RIGHT(0XF0A9), // + ARROW_CIRCLE_UP(0XF0AA), // + ARROW_DOWN(0XF063), // + ARROW_LEFT(0XF060), // + ARROW_RIGHT(0XF061), // + ARROW_UP(0XF062), // + ARROWS(0XF047), // + ARROWS_ALT(0XF0B2), // + ARROWS_H(0XF07E), // + ARROWS_V(0XF07D), // + ASTERISK(0XF069), // + AUTOMOBILE(0XF1B9), // + BACKWARD(0XF04A), // + BAN(0XF05E), // + BANK(0XF19C), // + BAR_CHART_O(0XF080), // BARCODE(0XF02A), // - TAG(0XF02B), // - TAGS(0XF02C), // + BARS(0XF0C9), // + BEER(0XF0FC), // + BEHANCE(0XF1B4), // + BEHANCE_SQUARE(0XF1B5), // + BELL(0XF0F3), // + BELL_O(0XF0A2), // + BITBUCKET(0XF171), // + BITBUCKET_SQUARE(0XF172), // + BITCOIN(0XF15A), // + BOLD(0XF032), // + BOLT(0XF0E7), // + BOMB(0XF1E2), // BOOK(0XF02D), // BOOKMARK(0XF02E), // - PRINT(0XF02F), // + BOOKMARK_O(0XF097), // + BRIEFCASE(0XF0B1), // + BTC(0XF15A), // + BUG(0XF188), // + BUILDING(0XF1AD), // + BUILDING_O(0XF0F7), // + BULLHORN(0XF0A1), // + BULLSEYE(0XF140), // + CAB(0XF1BA), // + CALENDAR(0XF073), // + CALENDAR_O(0XF133), // CAMERA(0XF030), // - FONT(0XF031), // - BOLD(0XF032), // - ITALIC(0XF033), // - TEXT_HEIGHT(0XF034), // - TEXT_WIDTH(0XF035), // - ALIGN_LEFT(0XF036), // - ALIGN_CENTER(0XF037), // - ALIGN_RIGHT(0XF038), // - ALIGN_JUSTIFY(0XF039), // - LIST(0XF03A), // - OUTDENT(0XF03B), // - INDENT(0XF03C), // - VIDEO_CAMERA(0XF03D), // - PICTURE_O(0XF03E), // - PENCIL(0XF040), // - MAP_MARKER(0XF041), // - ADJUST(0XF042), // - TINT(0XF043), // - PENCIL_SQUARE_O(0XF044), // - SHARE_SQUARE_O(0XF045), // + CAMERA_RETRO(0XF083), // + CAR(0XF1B9), // + CARET_DOWN(0XF0D7), // + CARET_LEFT(0XF0D9), // + CARET_RIGHT(0XF0DA), // + CARET_SQUARE_O_DOWN(0XF150), // + CARET_SQUARE_O_LEFT(0XF191), // + CARET_SQUARE_O_RIGHT(0XF152), // + CARET_SQUARE_O_UP(0XF151), // + CARET_UP(0XF0D8), // + CERTIFICATE(0XF0A3), // + CHAIN(0XF0C1), // + CHAIN_BROKEN(0XF127), // + CHECK(0XF00C), // + CHECK_CIRCLE(0XF058), // + CHECK_CIRCLE_O(0XF05D), // + CHECK_SQUARE(0XF14A), // CHECK_SQUARE_O(0XF046), // - ARROWS(0XF047), // - STEP_BACKWARD(0XF048), // - FAST_BACKWARD(0XF049), // - BACKWARD(0XF04A), // - PLAY(0XF04B), // - PAUSE(0XF04C), // - STOP(0XF04D), // - FORWARD(0XF04E), // - FAST_FORWARD(0XF050), // - STEP_FORWARD(0XF051), // - EJECT(0XF052), // + CHEVRON_CIRCLE_DOWN(0XF13A), // + CHEVRON_CIRCLE_LEFT(0XF137), // + CHEVRON_CIRCLE_RIGHT(0XF138), // + CHEVRON_CIRCLE_UP(0XF139), // + CHEVRON_DOWN(0XF078), // CHEVRON_LEFT(0XF053), // CHEVRON_RIGHT(0XF054), // - PLUS_CIRCLE(0XF055), // - MINUS_CIRCLE(0XF056), // - TIMES_CIRCLE(0XF057), // - CHECK_CIRCLE(0XF058), // - QUESTION_CIRCLE(0XF059), // - INFO_CIRCLE(0XF05A), // - CROSSHAIRS(0XF05B), // - TIMES_CIRCLE_O(0XF05C), // - CHECK_CIRCLE_O(0XF05D), // - BAN(0XF05E), // - ARROW_LEFT(0XF060), // - ARROW_RIGHT(0XF061), // - ARROW_UP(0XF062), // - ARROW_DOWN(0XF063), // - SHARE(0XF064), // - EXPAND(0XF065), // + CHEVRON_UP(0XF077), // + CHILD(0XF1AE), // + CIRCLE(0XF111), // + CIRCLE_O(0XF10C), // + CIRCLE_O_NOTCH(0XF1CE), // + CIRCLE_THIN(0XF1DB), // + CLIPBOARD(0XF0EA), // + CLOCK_O(0XF017), // + CLOUD(0XF0C2), // + CLOUD_DOWNLOAD(0XF0ED), // + CLOUD_UPLOAD(0XF0EE), // + CNY(0XF157), // + CODE(0XF121), // + CODE_FORK(0XF126), // + CODEPEN(0XF1CB), // + COFFEE(0XF0F4), // + COG(0XF013), // + COGS(0XF085), // + COLUMNS(0XF0DB), // + COMMENT(0XF075), // + COMMENT_O(0XF0E5), // + COMMENTS(0XF086), // + COMMENTS_O(0XF0E6), // + COMPASS(0XF14E), // COMPRESS(0XF066), // - PLUS(0XF067), // - MINUS(0XF068), // - ASTERISK(0XF069), // + COPY(0XF0C5), // + CREDIT_CARD(0XF09D), // + CROP(0XF125), // + CROSSHAIRS(0XF05B), // + CSS3(0XF13C), // + CUBE(0XF1B2), // + CUBES(0XF1B3), // + CUT(0XF0C4), // + CUTLERY(0XF0F5), // + DASHBOARD(0XF0E4), // + DATABASE(0XF1C0), // + DEDENT(0XF03B), // + DELICIOUS(0XF1A5), // + DESKTOP(0XF108), // + DEVIANTART(0XF1BD), // + DIGG(0XF1A6), // + DOLLAR(0XF155), // + DOT_CIRCLE_O(0XF192), // + DOWNLOAD(0XF019), // + DRIBBBLE(0XF17D), // + DROPBOX(0XF16B), // + DRUPAL(0XF1A9), // + EDIT(0XF044), // + EJECT(0XF052), // + ELLIPSIS_H(0XF141), // + ELLIPSIS_V(0XF142), // + EMPIRE(0XF1D1), // + ENVELOPE(0XF0E0), // + ENVELOPE_O(0XF003), // + ENVELOPE_SQUARE(0XF199), // + ERASER(0XF12D), // + EUR(0XF153), // + EURO(0XF153), // + EXCHANGE(0XF0EC), // + EXCLAMATION(0XF12A), // EXCLAMATION_CIRCLE(0XF06A), // - GIFT(0XF06B), // - LEAF(0XF06C), // - FIRE(0XF06D), // + EXCLAMATION_TRIANGLE(0XF071), // + EXPAND(0XF065), // + EXTERNAL_LINK(0XF08E), // + EXTERNAL_LINK_SQUARE(0XF14C), // EYE(0XF06E), // EYE_SLASH(0XF070), // - EXCLAMATION_TRIANGLE(0XF071), // - PLANE(0XF072), // - CALENDAR(0XF073), // - RANDOM(0XF074), // - COMMENT(0XF075), // - MAGNET(0XF076), // - CHEVRON_UP(0XF077), // - CHEVRON_DOWN(0XF078), // - RETWEET(0XF079), // - SHOPPING_CART(0XF07A), // + FACEBOOK(0XF09A), // + FACEBOOK_SQUARE(0XF082), // + FAST_BACKWARD(0XF049), // + FAST_FORWARD(0XF050), // + FAX(0XF1AC), // + FEMALE(0XF182), // + FIGHTER_JET(0XF0FB), // + FILE(0XF15B), // + FILE_ARCHIVE_O(0XF1C6), // + FILE_AUDIO_O(0XF1C7), // + FILE_CODE_O(0XF1C9), // + FILE_EXCEL_O(0XF1C3), // + FILE_IMAGE_O(0XF1C5), // + FILE_MOVIE_O(0XF1C8), // + FILE_O(0XF016), // + FILE_PDF_O(0XF1C1), // + FILE_PHOTO_O(0XF1C5), // + FILE_PICTURE_O(0XF1C5), // + FILE_POWERPOINT_O(0XF1C4), // + FILE_SOUND_O(0XF1C7), // + FILE_TEXT(0XF15C), // + FILE_TEXT_O(0XF0F6), // + FILE_VIDEO_O(0XF1C8), // + FILE_WORD_O(0XF1C2), // + FILE_ZIP_O(0XF1C6), // + FILES_O(0XF0C5), // + FILM(0XF008), // + FILTER(0XF0B0), // + FIRE(0XF06D), // + FIRE_EXTINGUISHER(0XF134), // + FLAG(0XF024), // + FLAG_CHECKERED(0XF11E), // + FLAG_O(0XF11D), // + FLASH(0XF0E7), // + FLASK(0XF0C3), // + FLICKR(0XF16E), // + FLOPPY_O(0XF0C7), // FOLDER(0XF07B), // + FOLDER_O(0XF114), // FOLDER_OPEN(0XF07C), // - ARROWS_V(0XF07D), // - ARROWS_H(0XF07E), // - BAR_CHART_O(0XF080), // - TWITTER_SQUARE(0XF081), // - FACEBOOK_SQUARE(0XF082), // - CAMERA_RETRO(0XF083), // - KEY(0XF084), // - COGS(0XF085), // - COMMENTS(0XF086), // - THUMBS_O_UP(0XF087), // - THUMBS_O_DOWN(0XF088), // - STAR_HALF(0XF089), // - HEART_O(0XF08A), // - SIGN_OUT(0XF08B), // - LINKEDIN_SQUARE(0XF08C), // - THUMB_TACK(0XF08D), // - EXTERNAL_LINK(0XF08E), // - SIGN_IN(0XF090), // - TROPHY(0XF091), // - GITHUB_SQUARE(0XF092), // - UPLOAD(0XF093), // - LEMON_O(0XF094), // - PHONE(0XF095), // - SQUARE_O(0XF096), // - BOOKMARK_O(0XF097), // - PHONE_SQUARE(0XF098), // - TWITTER(0XF099), // - FACEBOOK(0XF09A), // + FOLDER_OPEN_O(0XF115), // + FONT(0XF031), // + FORWARD(0XF04E), // + FOURSQUARE(0XF180), // + FROWN_O(0XF119), // + GAMEPAD(0XF11B), // + GAVEL(0XF0E3), // + GBP(0XF154), // + GE(0XF1D1), // + GEAR(0XF013), // + GEARS(0XF085), // + GIFT(0XF06B), // + GIT(0XF1D3), // + GIT_SQUARE(0XF1D2), // GITHUB(0XF09B), // - UNLOCK(0XF09C), // - CREDIT_CARD(0XF09D), // - RSS(0XF09E), // - HDD_O(0XF0A0), // - BULLHORN(0XF0A1), // - BELL(0XF0F3), // - CERTIFICATE(0XF0A3), // - HAND_O_RIGHT(0XF0A4), // + GITHUB_ALT(0XF113), // + GITHUB_SQUARE(0XF092), // + GITTIP(0XF184), // + GLASS(0XF000), // + GLOBE(0XF0AC), // + GOOGLE(0XF1A0), // + GOOGLE_PLUS(0XF0D5), // + GOOGLE_PLUS_SQUARE(0XF0D4), // + GRADUATION_CAP(0XF19D), // + GROUP(0XF0C0), // + H_SQUARE(0XF0FD), // + HACKER_NEWS(0XF1D4), // + HAND_O_DOWN(0XF0A7), // HAND_O_LEFT(0XF0A5), // + HAND_O_RIGHT(0XF0A4), // HAND_O_UP(0XF0A6), // - HAND_O_DOWN(0XF0A7), // - ARROW_CIRCLE_LEFT(0XF0A8), // - ARROW_CIRCLE_RIGHT(0XF0A9), // - ARROW_CIRCLE_UP(0XF0AA), // - ARROW_CIRCLE_DOWN(0XF0AB), // - GLOBE(0XF0AC), // - WRENCH(0XF0AD), // - TASKS(0XF0AE), // - FILTER(0XF0B0), // - BRIEFCASE(0XF0B1), // - ARROWS_ALT(0XF0B2), // - USERS(0XF0C0), // + HDD_O(0XF0A0), // + HEADER(0XF1DC), // + HEADPHONES(0XF025), // + HEART(0XF004), // + HEART_O(0XF08A), // + HISTORY(0XF1DA), // + HOME(0XF015), // + HOSPITAL_O(0XF0F8), // + HTML5(0XF13B), // + IMAGE(0XF03E), // + INBOX(0XF01C), // + INDENT(0XF03C), // + INFO(0XF129), // + INFO_CIRCLE(0XF05A), // + INR(0XF156), // + INSTAGRAM(0XF16D), // + INSTITUTION(0XF19C), // + ITALIC(0XF033), // + JOOMLA(0XF1AA), // + JPY(0XF157), // + JSFIDDLE(0XF1CC), // + KEY(0XF084), // + KEYBOARD_O(0XF11C), // + KRW(0XF159), // + LANGUAGE(0XF1AB), // + LAPTOP(0XF109), // + LEAF(0XF06C), // + LEGAL(0XF0E3), // + LEMON_O(0XF094), // + LEVEL_DOWN(0XF149), // + LEVEL_UP(0XF148), // + LIFE_BOUY(0XF1CD), // + LIFE_RING(0XF1CD), // + LIFE_SAVER(0XF1CD), // + LIGHTBULB_O(0XF0EB), // LINK(0XF0C1), // - CLOUD(0XF0C2), // - FLASK(0XF0C3), // - SCISSORS(0XF0C4), // - FILES_O(0XF0C5), // - PAPERCLIP(0XF0C6), // - FLOPPY_O(0XF0C7), // - SQUARE(0XF0C8), // - BARS(0XF0C9), // - LIST_UL(0XF0CA), // + LINKEDIN(0XF0E1), // + LINKEDIN_SQUARE(0XF08C), // + LINUX(0XF17C), // + LIST(0XF03A), // + LIST_ALT(0XF022), // LIST_OL(0XF0CB), // - STRIKETHROUGH(0XF0CC), // - UNDERLINE(0XF0CD), // - TABLE(0XF0CE), // + LIST_UL(0XF0CA), // + LOCATION_ARROW(0XF124), // + LOCK(0XF023), // + LONG_ARROW_DOWN(0XF175), // + LONG_ARROW_LEFT(0XF177), // + LONG_ARROW_RIGHT(0XF178), // + LONG_ARROW_UP(0XF176), // MAGIC(0XF0D0), // - TRUCK(0XF0D1), // + MAGNET(0XF076), // + MAIL_FORWARD(0XF064), // + MAIL_REPLY(0XF112), // + MAIL_REPLY_ALL(0XF122), // + MALE(0XF183), // + MAP_MARKER(0XF041), // + MAXCDN(0XF136), // + MEDKIT(0XF0FA), // + MEH_O(0XF11A), // + MICROPHONE(0XF130), // + MICROPHONE_SLASH(0XF131), // + MINUS(0XF068), // + MINUS_CIRCLE(0XF056), // + MINUS_SQUARE(0XF146), // + MINUS_SQUARE_O(0XF147), // + MOBILE(0XF10B), // + MOBILE_PHONE(0XF10B), // + MONEY(0XF0D6), // + MOON_O(0XF186), // + MORTAR_BOARD(0XF19D), // + MUSIC(0XF001), // + NAVICON(0XF0C9), // + OPENID(0XF19B), // + OUTDENT(0XF03B), // + PAGELINES(0XF18C), // + PAPER_PLANE(0XF1D8), // + PAPER_PLANE_O(0XF1D9), // + PAPERCLIP(0XF0C6), // + PARAGRAPH(0XF1DD), // + PASTE(0XF0EA), // + PAUSE(0XF04C), // + PAW(0XF1B0), // + PENCIL(0XF040), // + PENCIL_SQUARE(0XF14B), // + PENCIL_SQUARE_O(0XF044), // + PHONE(0XF095), // + PHONE_SQUARE(0XF098), // + PHOTO(0XF03E), // + PICTURE_O(0XF03E), // + PIED_PIPER(0XF1A7), // + PIED_PIPER_ALT(0XF1A8), // + PIED_PIPER_SQUARE(0XF1A7), // PINTEREST(0XF0D2), // PINTEREST_SQUARE(0XF0D3), // - GOOGLE_PLUS_SQUARE(0XF0D4), // - GOOGLE_PLUS(0XF0D5), // - MONEY(0XF0D6), // - CARET_DOWN(0XF0D7), // - CARET_UP(0XF0D8), // - CARET_LEFT(0XF0D9), // - CARET_RIGHT(0XF0DA), // - COLUMNS(0XF0DB), // - SORT(0XF0DC), // - SORT_ASC(0XF0DD), // - SORT_DESC(0XF0DE), // - ENVELOPE(0XF0E0), // - LINKEDIN(0XF0E1), // - UNDO(0XF0E2), // - GAVEL(0XF0E3), // - TACHOMETER(0XF0E4), // - COMMENT_O(0XF0E5), // - COMMENTS_O(0XF0E6), // - BOLT(0XF0E7), // - SITEMAP(0XF0E8), // - UMBRELLA(0XF0E9), // - CLIPBOARD(0XF0EA), // - LIGHTBULB_O(0XF0EB), // - EXCHANGE(0XF0EC), // - CLOUD_DOWNLOAD(0XF0ED), // - CLOUD_UPLOAD(0XF0EE), // - USER_MD(0XF0F0), // - STETHOSCOPE(0XF0F1), // - SUITCASE(0XF0F2), // - BELL_O(0XF0A2), // - COFFEE(0XF0F4), // - CUTLERY(0XF0F5), // - FILE_TEXT_O(0XF0F6), // - BUILDING_O(0XF0F7), // - HOSPITAL_O(0XF0F8), // - AMBULANCE(0XF0F9), // - MEDKIT(0XF0FA), // - FIGHTER_JET(0XF0FB), // - BEER(0XF0FC), // - H_SQUARE(0XF0FD), // + PLANE(0XF072), // + PLAY(0XF04B), // + PLAY_CIRCLE(0XF144), // + PLAY_CIRCLE_O(0XF01D), // + PLUS(0XF067), // + PLUS_CIRCLE(0XF055), // PLUS_SQUARE(0XF0FE), // - ANGLE_DOUBLE_LEFT(0XF100), // - ANGLE_DOUBLE_RIGHT(0XF101), // - ANGLE_DOUBLE_UP(0XF102), // - ANGLE_DOUBLE_DOWN(0XF103), // - ANGLE_LEFT(0XF104), // - ANGLE_RIGHT(0XF105), // - ANGLE_UP(0XF106), // - ANGLE_DOWN(0XF107), // - DESKTOP(0XF108), // - LAPTOP(0XF109), // - TABLET(0XF10A), // - MOBILE(0XF10B), // - CIRCLE_O(0XF10C), // + PLUS_SQUARE_O(0XF196), // + POWER_OFF(0XF011), // + PRINT(0XF02F), // + PUZZLE_PIECE(0XF12E), // + QQ(0XF1D6), // + QRCODE(0XF029), // + QUESTION(0XF128), // + QUESTION_CIRCLE(0XF059), // QUOTE_LEFT(0XF10D), // QUOTE_RIGHT(0XF10E), // - SPINNER(0XF110), // - CIRCLE(0XF111), // + RA(0XF1D0), // + RANDOM(0XF074), // + REBEL(0XF1D0), // + RECYCLE(0XF1B8), // + REDDIT(0XF1A1), // + REDDIT_SQUARE(0XF1A2), // + REFRESH(0XF021), // + RENREN(0XF18B), // + REORDER(0XF0C9), // + REPEAT(0XF01E), // REPLY(0XF112), // - GITHUB_ALT(0XF113), // - FOLDER_O(0XF114), // - FOLDER_OPEN_O(0XF115), // - SMILE_O(0XF118), // - FROWN_O(0XF119), // - MEH_O(0XF11A), // - GAMEPAD(0XF11B), // - KEYBOARD_O(0XF11C), // - FLAG_O(0XF11D), // - FLAG_CHECKERED(0XF11E), // - TERMINAL(0XF120), // - CODE(0XF121), // REPLY_ALL(0XF122), // - MAIL_REPLY_ALL(0XF122), // - STAR_HALF_O(0XF123), // - LOCATION_ARROW(0XF124), // - CROP(0XF125), // - CODE_FORK(0XF126), // - CHAIN_BROKEN(0XF127), // - QUESTION(0XF128), // - INFO(0XF129), // - EXCLAMATION(0XF12A), // - SUPERSCRIPT(0XF12B), // - SUBSCRIPT(0XF12C), // - ERASER(0XF12D), // - PUZZLE_PIECE(0XF12E), // - MICROPHONE(0XF130), // - MICROPHONE_SLASH(0XF131), // - SHIELD(0XF132), // - CALENDAR_O(0XF133), // - FIRE_EXTINGUISHER(0XF134), // + RETWEET(0XF079), // + RMB(0XF157), // + ROAD(0XF018), // ROCKET(0XF135), // - MAXCDN(0XF136), // - CHEVRON_CIRCLE_LEFT(0XF137), // - CHEVRON_CIRCLE_RIGHT(0XF138), // - CHEVRON_CIRCLE_UP(0XF139), // - CHEVRON_CIRCLE_DOWN(0XF13A), // - HTML5(0XF13B), // - CSS3(0XF13C), // - ANCHOR(0XF13D), // - UNLOCK_ALT(0XF13E), // - BULLSEYE(0XF140), // - ELLIPSIS_H(0XF141), // - ELLIPSIS_V(0XF142), // + ROTATE_LEFT(0XF0E2), // + ROTATE_RIGHT(0XF01E), // + ROUBLE(0XF158), // + RSS(0XF09E), // RSS_SQUARE(0XF143), // - PLAY_CIRCLE(0XF144), // - TICKET(0XF145), // - MINUS_SQUARE(0XF146), // - MINUS_SQUARE_O(0XF147), // - LEVEL_UP(0XF148), // - LEVEL_DOWN(0XF149), // - CHECK_SQUARE(0XF14A), // - PENCIL_SQUARE(0XF14B), // - EXTERNAL_LINK_SQUARE(0XF14C), // - SHARE_SQUARE(0XF14D), // - COMPASS(0XF14E), // - CARET_SQUARE_O_DOWN(0XF150), // - CARET_SQUARE_O_UP(0XF151), // - CARET_SQUARE_O_RIGHT(0XF152), // - EUR(0XF153), // - GBP(0XF154), // - USD(0XF155), // - INR(0XF156), // - JPY(0XF157), // RUB(0XF158), // - KRW(0XF159), // - BTC(0XF15A), // - FILE(0XF15B), // - FILE_TEXT(0XF15C), // + RUBLE(0XF158), // + RUPEE(0XF156), // + SAVE(0XF0C7), // + SCISSORS(0XF0C4), // + SEARCH(0XF002), // + SEARCH_MINUS(0XF010), // + SEARCH_PLUS(0XF00E), // + SEND(0XF1D8), // + SEND_O(0XF1D9), // + SHARE(0XF064), // + SHARE_ALT(0XF1E0), // + SHARE_ALT_SQUARE(0XF1E1), // + SHARE_SQUARE(0XF14D), // + SHARE_SQUARE_O(0XF045), // + SHIELD(0XF132), // + SHOPPING_CART(0XF07A), // + SIGN_IN(0XF090), // + SIGN_OUT(0XF08B), // + SIGNAL(0XF012), // + SITEMAP(0XF0E8), // + SKYPE(0XF17E), // + SLACK(0XF198), // + SLIDERS(0XF1DE), // + SMILE_O(0XF118), // + SORT(0XF0DC), // SORT_ALPHA_ASC(0XF15D), // SORT_ALPHA_DESC(0XF15E), // SORT_AMOUNT_ASC(0XF160), // SORT_AMOUNT_DESC(0XF161), // + SORT_ASC(0XF0DE), // + SORT_DESC(0XF0DD), // + SORT_DOWN(0XF0DD), // SORT_NUMERIC_ASC(0XF162), // SORT_NUMERIC_DESC(0XF163), // - THUMBS_UP(0XF164), // - THUMBS_DOWN(0XF165), // - YOUTUBE_SQUARE(0XF166), // - YOUTUBE(0XF167), // - XING(0XF168), // - XING_SQUARE(0XF169), // - YOUTUBE_PLAY(0XF16A), // - DROPBOX(0XF16B), // + SORT_UP(0XF0DE), // + SOUNDCLOUD(0XF1BE), // + SPACE_SHUTTLE(0XF197), // + SPINNER(0XF110), // + SPOON(0XF1B1), // + SPOTIFY(0XF1BC), // + SQUARE(0XF0C8), // + SQUARE_O(0XF096), // + STACK_EXCHANGE(0XF18D), // STACK_OVERFLOW(0XF16C), // - INSTAGRAM(0XF16D), // - FLICKR(0XF16E), // - ADN(0XF170), // - BITBUCKET(0XF171), // - BITBUCKET_SQUARE(0XF172), // + STAR(0XF005), // + STAR_HALF(0XF089), // + STAR_HALF_EMPTY(0XF123), // + STAR_HALF_FULL(0XF123), // + STAR_HALF_O(0XF123), // + STAR_O(0XF006), // + STEAM(0XF1B6), // + STEAM_SQUARE(0XF1B7), // + STEP_BACKWARD(0XF048), // + STEP_FORWARD(0XF051), // + STETHOSCOPE(0XF0F1), // + STOP(0XF04D), // + STRIKETHROUGH(0XF0CC), // + STUMBLEUPON(0XF1A4), // + STUMBLEUPON_CIRCLE(0XF1A3), // + SUBSCRIPT(0XF12C), // + SUITCASE(0XF0F2), // + SUN_O(0XF185), // + SUPERSCRIPT(0XF12B), // + SUPPORT(0XF1CD), // + TABLE(0XF0CE), // + TABLET(0XF10A), // + TACHOMETER(0XF0E4), // + TAG(0XF02B), // + TAGS(0XF02C), // + TASKS(0XF0AE), // + TAXI(0XF1BA), // + TENCENT_WEIBO(0XF1D5), // + TERMINAL(0XF120), // + TEXT_HEIGHT(0XF034), // + TEXT_WIDTH(0XF035), // + TH(0XF00A), // + TH_LARGE(0XF009), // + TH_LIST(0XF00B), // + THUMB_TACK(0XF08D), // + THUMBS_DOWN(0XF165), // + THUMBS_O_DOWN(0XF088), // + THUMBS_O_UP(0XF087), // + THUMBS_UP(0XF164), // + TICKET(0XF145), // + TIMES(0XF00D), // + TIMES_CIRCLE(0XF057), // + TIMES_CIRCLE_O(0XF05C), // + TINT(0XF043), // + TOGGLE_DOWN(0XF150), // + TOGGLE_LEFT(0XF191), // + TOGGLE_RIGHT(0XF152), // + TOGGLE_UP(0XF151), // + TRASH_O(0XF014), // + TREE(0XF1BB), // + TRELLO(0XF181), // + TROPHY(0XF091), // + TRUCK(0XF0D1), // + TRY(0XF195), // TUMBLR(0XF173), // TUMBLR_SQUARE(0XF174), // - LONG_ARROW_DOWN(0XF175), // - LONG_ARROW_UP(0XF176), // - LONG_ARROW_LEFT(0XF177), // - LONG_ARROW_RIGHT(0XF178), // - APPLE(0XF179), // - WINDOWS(0XF17A), // - ANDROID(0XF17B), // - LINUX(0XF17C), // - DRIBBBLE(0XF17D), // - SKYPE(0XF17E), // - FOURSQUARE(0XF180), // - TRELLO(0XF181), // - FEMALE(0XF182), // - MALE(0XF183), // - GITTIP(0XF184), // - SUN_O(0XF185), // - MOON_O(0XF186), // - ARCHIVE(0XF187), // - BUG(0XF188), // + TURKISH_LIRA(0XF195), // + TWITTER(0XF099), // + TWITTER_SQUARE(0XF081), // + UMBRELLA(0XF0E9), // + UNDERLINE(0XF0CD), // + UNDO(0XF0E2), // + UNIVERSITY(0XF19C), // + UNLINK(0XF127), // + UNLOCK(0XF09C), // + UNLOCK_ALT(0XF13E), // + UNSORTED(0XF0DC), // + UPLOAD(0XF093), // + USD(0XF155), // + USER(0XF007), // + USER_MD(0XF0F0), // + USERS(0XF0C0), // + VIDEO_CAMERA(0XF03D), // + VIMEO_SQUARE(0XF194), // + VINE(0XF1CA), // VK(0XF189), // + VOLUME_DOWN(0XF027), // + VOLUME_OFF(0XF026), // + VOLUME_UP(0XF028), // + WARNING(0XF071), // + WECHAT(0XF1D7), // WEIBO(0XF18A), // - RENREN(0XF18B), // - PAGELINES(0XF18C), // - STACK_EXCHANGE(0XF18D), // - ARROW_CIRCLE_O_RIGHT(0XF18E), // - ARROW_CIRCLE_O_LEFT(0XF190), // - CARET_SQUARE_O_LEFT(0XF191), // - DOT_CIRCLE_O(0XF192), // + WEIXIN(0XF1D7), // WHEELCHAIR(0XF193), // - VIMEO_SQUARE(0XF194), // - TRY(0XF195), // - PLUS_SQUARE_O(0XF196); + WINDOWS(0XF17A), // + WON(0XF159), // + WORDPRESS(0XF19A), // + WRENCH(0XF0AD), // + XING(0XF168), // + XING_SQUARE(0XF169), // + YAHOO(0XF19E), // + YEN(0XF157), // + YOUTUBE(0XF167), // + YOUTUBE_PLAY(0XF16A), // + YOUTUBE_SQUARE(0XF166); private static final String fontFamily = "FontAwesome"; private int codepoint; diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java index 93074abcdb..34b05f73bf 100644 --- a/server/src/com/vaadin/server/JsonCodec.java +++ b/server/src/com/vaadin/server/JsonCodec.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -56,7 +56,7 @@ import com.vaadin.ui.ConnectorTracker; /** * Decoder for converting RPC parameters and other values from JSON in transfer * between the client and the server and vice versa. - * + * * @since 7.0 */ public class JsonCodec implements Serializable { @@ -119,9 +119,9 @@ public class JsonCodec implements Serializable { public static Collection<FieldProperty> find(Class<?> type) throws IntrospectionException { - Collection<FieldProperty> properties = new ArrayList<FieldProperty>(); - Field[] fields = type.getFields(); + Collection<FieldProperty> properties = new ArrayList<FieldProperty>( + fields.length); for (Field field : fields) { if (!Modifier.isStatic(field.getModifiers())) { properties.add(new FieldProperty(field)); @@ -341,7 +341,7 @@ public class JsonCodec implements Serializable { * using the declared type. Otherwise only internal types are allowed in * collections. * </p> - * + * * @param targetType * The type that should be returned by this method * @param valueAndType @@ -471,13 +471,13 @@ public class JsonCodec implements Serializable { private static Map<Object, Object> decodeObjectMap(Type keyType, Type valueType, JSONArray jsonMap, ConnectorTracker connectorTracker) throws JSONException { - Map<Object, Object> map = new HashMap<Object, Object>(); JSONArray keys = jsonMap.getJSONArray(0); JSONArray values = jsonMap.getJSONArray(1); assert (keys.length() == values.length()); + Map<Object, Object> map = new HashMap<Object, Object>(keys.length() * 2); for (int i = 0; i < keys.length(); i++) { Object key = decodeInternalOrCustomType(keyType, keys.get(i), connectorTracker); @@ -580,8 +580,9 @@ public class JsonCodec implements Serializable { private static List<Object> decodeList(Type targetType, boolean restrictToInternalTypes, JSONArray jsonArray, ConnectorTracker connectorTracker) throws JSONException { - List<Object> list = new ArrayList<Object>(); - for (int i = 0; i < jsonArray.length(); ++i) { + int arrayLength = jsonArray.length(); + List<Object> list = new ArrayList<Object>(arrayLength); + for (int i = 0; i < arrayLength; ++i) { // each entry always has two elements: type and value Object encodedValue = jsonArray.get(i); Object decodedChild = decodeParametrizedType(targetType, @@ -754,7 +755,7 @@ public class JsonCodec implements Serializable { /** * Compares the value with the reference. If they match, returns true. - * + * * @param fieldValue * @param referenceValue * @return diff --git a/server/src/com/vaadin/server/Page.java b/server/src/com/vaadin/server/Page.java index d58ba548e3..3acea97c0f 100644 --- a/server/src/com/vaadin/server/Page.java +++ b/server/src/com/vaadin/server/Page.java @@ -636,7 +636,8 @@ public class Page implements Serializable { } public void init(VaadinRequest request) { - // NOTE: UI.refresh makes assumptions about the semantics of this method. + // NOTE: UI.refresh makes assumptions about the semantics of this + // method. // It should be kept in sync if this method is changed. // Extract special parameter sent by vaadinBootstrap.js diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index e8cdcd7055..8d44ff74ed 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -34,6 +34,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; @@ -69,9 +70,9 @@ import com.vaadin.util.ReflectTools; /** * Provide deployment specific settings that are required outside terminal * specific code. - * + * * @author Vaadin Ltd. - * + * * @since 7.0 */ public abstract class VaadinService implements Serializable { @@ -144,7 +145,7 @@ public abstract class VaadinService implements Serializable { /** * Creates a new vaadin service based on a deployment configuration - * + * * @param deploymentConfiguration * the deployment configuration for the service */ @@ -172,7 +173,7 @@ public abstract class VaadinService implements Serializable { /** * Initializes this service. The service should be initialized before it is * used. - * + * * @since 7.1 * @throws ServiceException * if a problem occurs when creating the service @@ -191,7 +192,7 @@ public abstract class VaadinService implements Serializable { * called first. This enables overriding this method and using add on the * returned list to add a custom request handler which overrides any * predefined handler. - * + * * @return The list of request handlers used by this service. * @throws ServiceException * if a problem occurs when creating the request handlers @@ -214,13 +215,13 @@ public abstract class VaadinService implements Serializable { * Return the URL from where static files, e.g. the widgetset and the theme, * are served. In a standard configuration the VAADIN folder inside the * returned folder is what is used for widgetsets and themes. - * + * * The returned folder is usually the same as the context path and * independent of e.g. the servlet mapping. - * + * * @param request * the request for which the location should be determined - * + * * @return The location of static resources (should contain the VAADIN * directory). Never ends with a slash (/). */ @@ -229,7 +230,7 @@ public abstract class VaadinService implements Serializable { /** * Gets the widgetset that is configured for this deployment, e.g. from a * parameter in web.xml. - * + * * @param request * the request for which a widgetset is required * @return the name of the widgetset @@ -239,7 +240,7 @@ public abstract class VaadinService implements Serializable { /** * Gets the theme that is configured for this deployment, e.g. from a portal * parameter or just some sensible default value. - * + * * @param request * the request for which a theme is required * @return the name of the theme @@ -251,7 +252,7 @@ public abstract class VaadinService implements Serializable { * whether it will be included into some other context. A standalone UI may * do things that might interfere with other parts of a page, e.g. changing * the page title and requesting focus upon loading. - * + * * @param request * the request for which the UI is loaded * @return a boolean indicating whether the UI should be standalone @@ -262,9 +263,9 @@ public abstract class VaadinService implements Serializable { * Gets the class loader to use for loading classes loaded by name, e.g. * custom UI classes. This is by default the class loader that was used to * load the Servlet or Portlet class to which this service belongs. - * + * * @return the class loader to use, or <code>null</code> - * + * * @see #setClassLoader(ClassLoader) */ public ClassLoader getClassLoader() { @@ -277,10 +278,10 @@ public abstract class VaadinService implements Serializable { * any existing class loader hierarchy, e.g. by ensuring that a class loader * set for this service delegates to the previously set class loader if the * class is not found. - * + * * @param classLoader * the new class loader to set, not <code>null</code>. - * + * * @see #getClassLoader() */ public void setClassLoader(ClassLoader classLoader) { @@ -296,11 +297,11 @@ public abstract class VaadinService implements Serializable { * not known. The MIME type is determined by the configuration of the * container, and may be specified in a deployment descriptor. Common MIME * types are "text/html" and "image/gif". - * + * * @param resourceName * a String specifying the name of a file * @return a String specifying the file's MIME type - * + * * @see ServletContext#getMimeType(String) * @see PortletContext#getMimeType(String) */ @@ -308,7 +309,7 @@ public abstract class VaadinService implements Serializable { /** * Gets the deployment configuration. - * + * * @return the deployment configuration */ public DeploymentConfiguration getDeploymentConfiguration() { @@ -318,9 +319,9 @@ public abstract class VaadinService implements Serializable { /** * Sets the system messages provider to use for getting system messages to * display to users of this service. - * + * * @see #getSystemMessagesProvider() - * + * * @param systemMessagesProvider * the system messages provider; <code>null</code> is not * allowed. @@ -340,11 +341,11 @@ public abstract class VaadinService implements Serializable { * By default, the {@link DefaultSystemMessagesProvider} which always * provides the built-in default {@link SystemMessages} is used. * </p> - * + * * @see #setSystemMessagesProvider(SystemMessagesProvider) * @see SystemMessagesProvider * @see SystemMessages - * + * * @return the system messages provider; not <code>null</code> */ public SystemMessagesProvider getSystemMessagesProvider() { @@ -356,7 +357,7 @@ public abstract class VaadinService implements Serializable { * also be implemented to use information from current instances of various * objects, which means that this method might return different values for * the same locale under different circumstances. - * + * * @param locale * the desired locale for the system messages * @param request @@ -373,13 +374,13 @@ public abstract class VaadinService implements Serializable { /** * Returns the context base directory. - * + * * Typically an application is deployed in a such way that is has an * application directory. For web applications this directory is the root * directory of the web applications. In some cases applications might not * have an application directory (for example web applications running * inside a war). - * + * * @return The application base directory or null if the application has no * base directory. */ @@ -393,10 +394,10 @@ public abstract class VaadinService implements Serializable { * the listener is not necessarily notified immediately when the session is * created but only when the first request for that session is handled by * this service. - * + * * @see #removeSessionInitListener(SessionInitListener) * @see SessionInitListener - * + * * @param listener * the Vaadin service session initialization listener */ @@ -408,9 +409,9 @@ public abstract class VaadinService implements Serializable { /** * Removes a Vaadin service session initialization listener from this * service. - * + * * @see #addSessionInitListener(SessionInitListener) - * + * * @param listener * the Vaadin service session initialization listener to remove. */ @@ -425,9 +426,9 @@ public abstract class VaadinService implements Serializable { * <p> * The session being destroyed is locked and its UIs have been removed when * the listeners are called. - * + * * @see #addSessionInitListener(SessionInitListener) - * + * * @param listener * the vaadin service session destroy listener */ @@ -439,7 +440,7 @@ public abstract class VaadinService implements Serializable { /** * Handles destruction of the given session. Internally ensures proper * locking is done. - * + * * @param vaadinSession * The session to destroy */ @@ -485,9 +486,9 @@ public abstract class VaadinService implements Serializable { /** * Removes a Vaadin service session destroy listener from this service. - * + * * @see #addSessionDestroyListener(SessionDestroyListener) - * + * * @param listener * the vaadin service session destroy listener */ @@ -502,12 +503,12 @@ public abstract class VaadinService implements Serializable { * Handles locking of the session internally to avoid creation of duplicate * sessions by two threads simultaneously. * </p> - * + * * @param request * the request to get a vaadin service session for. - * + * * @see VaadinSession - * + * * @return the vaadin service session for the request, or <code>null</code> * if no session is found and this is a request for which a new * session shouldn't be created. @@ -529,7 +530,7 @@ public abstract class VaadinService implements Serializable { * Associates the given lock with this service and the given wrapped * session. This method should not be called more than once when the lock is * initialized for the session. - * + * * @see #getSessionLock(WrappedSession) * @param wrappedSession * The wrapped session the lock is associated with @@ -550,7 +551,7 @@ public abstract class VaadinService implements Serializable { /** * Returns the name used to store the lock in the HTTP session. - * + * * @return The attribute name for the lock */ private String getLockAttributeName() { @@ -564,7 +565,7 @@ public abstract class VaadinService implements Serializable { * This method uses the wrapped session instead of VaadinSession to be able * to lock even before the VaadinSession has been initialized. * </p> - * + * * @param wrappedSession * The wrapped session * @return A lock instance used for locking access to the wrapped session @@ -588,10 +589,10 @@ public abstract class VaadinService implements Serializable { /** * Locks the given session for this service instance. Typically you want to * call {@link VaadinSession#lock()} instead of this method. - * + * * @param wrappedSession * The session to lock - * + * * @throws IllegalStateException * if the session is invalidated before it can be locked */ @@ -631,7 +632,7 @@ public abstract class VaadinService implements Serializable { * Releases the lock for the given session for this service instance. * Typically you want to call {@link VaadinSession#unlock()} instead of this * method. - * + * * @param wrappedSession * The session to unlock */ @@ -666,7 +667,7 @@ public abstract class VaadinService implements Serializable { * Finds or creates a Vaadin session. Assumes necessary synchronization has * been done by the caller to ensure this is not called simultaneously by * several threads. - * + * * @param request * @param requestCanCreateSession * @return @@ -733,8 +734,8 @@ public abstract class VaadinService implements Serializable { /** * Creates and registers a new VaadinSession for this service. Assumes * proper locking has been taken care of by the caller. - * - * + * + * * @param request * The request which triggered session creation. * @return A new VaadinSession instance @@ -771,11 +772,11 @@ public abstract class VaadinService implements Serializable { * service. * <p> * This is only used to support legacy cases. - * + * * @param request * @return * @throws MalformedURLException - * + * * @deprecated As of 7.0. Only used to support {@link LegacyApplication}. */ @Deprecated @@ -786,12 +787,12 @@ public abstract class VaadinService implements Serializable { /** * Creates a new Vaadin session for this service and request - * + * * @param request * The request for which to create a VaadinSession * @return A new VaadinSession * @throws ServiceException - * + * */ protected VaadinSession createVaadinSession(VaadinRequest request) throws ServiceException { @@ -839,7 +840,7 @@ public abstract class VaadinService implements Serializable { /** * Retrieves the wrapped session for the request. - * + * * @param request * The request for which to retrieve a session * @param requestCanCreateSession @@ -862,7 +863,7 @@ public abstract class VaadinService implements Serializable { /** * Checks whether it's valid to create a new service session as a result of * the given request. - * + * * @param request * the request * @return <code>true</code> if it's valid to create a new service session @@ -877,10 +878,10 @@ public abstract class VaadinService implements Serializable { * {@link InheritableThreadLocal}). In other cases, (e.g. from background * threads started in some other way), the current service is not * automatically defined. - * + * * @return the current Vaadin service instance if available, otherwise * <code>null</code> - * + * * @see #setCurrentInstances(VaadinRequest, VaadinResponse) */ public static VaadinService getCurrent() { @@ -898,14 +899,14 @@ public abstract class VaadinService implements Serializable { * instances outside the normal request handling, e.g. when initiating * custom background threads. * </p> - * + * * @param request * the Vaadin request to set as the current request, or * <code>null</code> if no request should be set. * @param response * the Vaadin response to set as the current response, or * <code>null</code> if no response should be set. - * + * * @see #getCurrent() * @see #getCurrentRequest() * @see #getCurrentResponse() @@ -919,7 +920,7 @@ public abstract class VaadinService implements Serializable { /** * Sets the given Vaadin service as the current service. - * + * * @param service */ public static void setCurrent(VaadinService service) { @@ -931,10 +932,10 @@ public abstract class VaadinService implements Serializable { * automatically defined when the request is started. The current request * can not be used in e.g. background threads because of the way server * implementations reuse request instances. - * + * * @return the current Vaadin request instance if available, otherwise * <code>null</code> - * + * * @see #setCurrentInstances(VaadinRequest, VaadinResponse) */ public static VaadinRequest getCurrentRequest() { @@ -946,10 +947,10 @@ public abstract class VaadinService implements Serializable { * automatically defined when the request is started. The current response * can not be used in e.g. background threads because of the way server * implementations reuse response instances. - * + * * @return the current Vaadin response instance if available, otherwise * <code>null</code> - * + * * @see #setCurrentInstances(VaadinRequest, VaadinResponse) */ public static VaadinResponse getCurrentResponse() { @@ -961,7 +962,7 @@ public abstract class VaadinService implements Serializable { * different services of the same type but the same for corresponding * instances running in different JVMs in a cluster. This is typically based * on e.g. the configured servlet's or portlet's name. - * + * * @return the unique name of this service instance. */ public abstract String getServiceName(); @@ -972,11 +973,11 @@ public abstract class VaadinService implements Serializable { * related to any particular UI or have the UI information encoded in a * non-standard way. The returned UI is also set as the current UI ( * {@link UI#setCurrent(UI)}). - * + * * @param request * the request for which a UI is desired * @return the UI belonging to the request or null if no UI is found - * + * */ public UI findUI(VaadinRequest request) { // getForSession asserts that the lock is held @@ -1002,12 +1003,12 @@ public abstract class VaadinService implements Serializable { * typically checks the @{@link PreserveOnRefresh} annotation but UI * providers and ultimately VaadinService implementations may choose to * override the defaults. - * + * * @param provider * the UI provider responsible for the UI * @param event * the UI create event with details about the UI - * + * * @return <code>true</code> if the UI should be preserved on refresh; * <code>false</code> if a new UI instance should be initialized on * refreshed. @@ -1024,7 +1025,7 @@ public abstract class VaadinService implements Serializable { * Please note that this method makes certain assumptions about how data is * stored in the underlying session and may thus not be compatible with some * environments. - * + * * @param request * The Vaadin request for which the session should be * reinitialized @@ -1034,8 +1035,10 @@ public abstract class VaadinService implements Serializable { // Stores all attributes (security key, reference to this context // instance) so they can be added to the new session - HashMap<String, Object> attrs = new HashMap<String, Object>(); - for (String name : oldSession.getAttributeNames()) { + Set<String> attributeNames = oldSession.getAttributeNames(); + HashMap<String, Object> attrs = new HashMap<String, Object>( + attributeNames.size() * 2); + for (String name : attributeNames) { Object value = oldSession.getAttribute(name); if (value instanceof VaadinSession) { // set flag to avoid cleanup @@ -1076,9 +1079,9 @@ public abstract class VaadinService implements Serializable { /** * TODO PUSH Document - * + * * TODO Pass UI or VaadinSession? - * + * * @param uI * @param themeName * @param resource @@ -1090,14 +1093,14 @@ public abstract class VaadinService implements Serializable { /** * Creates and returns a unique ID for the DIV where the UI is to be * rendered. - * + * * @param session * The service session to which the bootstrapped UI will belong. * @param request * The request for which a div id is needed * @param uiClass * The class of the UI that will be bootstrapped - * + * * @return the id to use in the DOM */ public abstract String getMainDivId(VaadinSession session, @@ -1115,9 +1118,9 @@ public abstract class VaadinService implements Serializable { * To avoid causing out of sync errors, you should typically redirect to * some other page using {@link Page#setLocation(String)} to make the * browser unload the invalidated UI. - * + * * @see SystemMessages#getSessionExpiredCaption() - * + * * @param session * the session to close */ @@ -1129,7 +1132,7 @@ public abstract class VaadinService implements Serializable { * Called at the end of a request, after sending the response. Closes * inactive UIs in the given session, removes closed UIs from the session, * and closes the session if it is itself inactive. - * + * * @param session */ void cleanupSession(VaadinSession session) { @@ -1164,29 +1167,29 @@ public abstract class VaadinService implements Serializable { /** * Removes those UIs from the given session for which {@link UI#isClosing() * isClosing} yields true. - * + * * @param session */ private void removeClosedUIs(final VaadinSession session) { ArrayList<UI> uis = new ArrayList<UI>(session.getUIs()); for (final UI ui : uis) { - ui.accessSynchronously(new Runnable() { - @Override - public void run() { - if (ui.isClosing()) { + if (ui.isClosing()) { + ui.accessSynchronously(new Runnable() { + @Override + public void run() { getLogger().log(Level.FINER, "Removing closed UI {0}", ui.getUIId()); session.removeUI(ui); } - } - }); + }); + } } } /** * Closes those UIs in the given session for which {@link #isUIActive} * yields false. - * + * * @since 7.0.0 */ private void closeInactiveUIs(VaadinSession session) { @@ -1212,11 +1215,11 @@ public abstract class VaadinService implements Serializable { * session. This is a lower bound; it might take longer to close an inactive * UI. Returns a negative number if heartbeat is disabled and timeout never * occurs. - * + * * @see DeploymentConfiguration#getHeartbeatInterval() - * + * * @since 7.0.0 - * + * * @return The heartbeat timeout in seconds or a negative number if timeout * never occurs. */ @@ -1235,12 +1238,12 @@ public abstract class VaadinService implements Serializable { * requests suffice to keep the session alive, but it will still eventually * expire in the regular manner if there are no requests at all (see * {@link WrappedSession#getMaxInactiveInterval()}). - * + * * @see DeploymentConfiguration#isCloseIdleSessions() * @see #getHeartbeatTimeout() - * + * * @since 7.0.0 - * + * * @return The UIDL request timeout in seconds, or a negative number if * timeout never occurs. */ @@ -1257,12 +1260,12 @@ public abstract class VaadinService implements Serializable { * A UI is active if and only if its {@link UI#isClosing() isClosing} * returns false and {@link #getHeartbeatTimeout() getHeartbeatTimeout} is * negative or has not yet expired. - * + * * @since 7.0.0 - * + * * @param ui * The UI whose status to check - * + * * @return true if the UI is active, false if it could be removed. */ private boolean isUIActive(UI ui) { @@ -1282,10 +1285,10 @@ public abstract class VaadinService implements Serializable { * A session is active if and only if its {@link #isClosing} returns false * and {@link #getUidlRequestTimeout(VaadinSession) getUidlRequestTimeout} * is negative or has not yet expired. - * + * * @param session * The session whose status to check - * + * * @return true if the session is active, false if it could be closed. */ private boolean isSessionActive(VaadinSession session) { @@ -1305,7 +1308,7 @@ public abstract class VaadinService implements Serializable { /** * Called before the framework starts handling a request - * + * * @param request * The request * @param response @@ -1323,7 +1326,7 @@ public abstract class VaadinService implements Serializable { /** * Called after the framework has handled a request and the response has * been written. - * + * * @param request * The request object * @param response @@ -1335,23 +1338,16 @@ public abstract class VaadinService implements Serializable { public void requestEnd(VaadinRequest request, VaadinResponse response, VaadinSession session) { if (session != null) { - final VaadinSession finalSession = session; - - session.accessSynchronously(new Runnable() { - @Override - public void run() { - cleanupSession(finalSession); - } - }); - - final long duration = (System.nanoTime() - (Long) request - .getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000; - session.accessSynchronously(new Runnable() { - @Override - public void run() { - finalSession.setLastRequestDuration(duration); - } - }); + assert VaadinSession.getCurrent() == session; + session.lock(); + try { + cleanupSession(session); + final long duration = (System.nanoTime() - (Long) request + .getAttribute(REQUEST_START_TIME_ATTRIBUTE)) / 1000000; + session.setLastRequestDuration(duration); + } finally { + session.unlock(); + } } CurrentInstance.clearAll(); } @@ -1360,11 +1356,11 @@ public abstract class VaadinService implements Serializable { * Returns the request handlers that are registered with this service. The * iteration order of the returned collection is the same as the order in * which the request handlers will be invoked when a request is handled. - * + * * @return a collection of request handlers in the order they are invoked - * + * * @see #createRequestHandlers() - * + * * @since 7.1 */ public Iterable<RequestHandler> getRequestHandlers() { @@ -1381,7 +1377,7 @@ public abstract class VaadinService implements Serializable { * request handler handles session expiration a default expiration message * will be written. * </p> - * + * * @param request * The incoming request * @param response @@ -1473,7 +1469,7 @@ public abstract class VaadinService implements Serializable { /** * Writes the given string as a response using the given content type. - * + * * @param response * The response reference * @param contentType @@ -1498,7 +1494,7 @@ public abstract class VaadinService implements Serializable { /** * Called when the session has expired and the request handling is therefore * aborted. - * + * * @param request * The request * @param response @@ -1553,7 +1549,7 @@ public abstract class VaadinService implements Serializable { /** * Creates a JSON message which, when sent to client as-is, will cause a * critical error to be shown with the given details. - * + * * @param caption * The caption of the error or null to omit * @param message @@ -1616,10 +1612,10 @@ public abstract class VaadinService implements Serializable { /** * Enables push if push support is available and push has not yet been * enabled. - * + * * If push support is not available, a warning explaining the situation will * be logged at least the first time this method is invoked. - * + * * @return <code>true</code> if push can be used; <code>false</code> if push * is not available. */ @@ -1638,7 +1634,7 @@ public abstract class VaadinService implements Serializable { * internally used by {@link VaadinSession#accessSynchronously(Runnable)} * and {@link UI#accessSynchronously(Runnable)} to help avoid causing * deadlocks. - * + * * @since 7.1 * @param session * the session that is being locked @@ -1657,7 +1653,7 @@ public abstract class VaadinService implements Serializable { * provided one for which the current thread holds a lock. This method might * not detect all cases where some other session is locked, but it should * cover the most typical situations. - * + * * @since 7.2 * @param session * the session that is expected to be locked @@ -1681,11 +1677,11 @@ public abstract class VaadinService implements Serializable { * to allow a certain type of testing. For these cases, the check can be * disabled by setting the init parameter * <code>disable-xsrf-protection</code> to <code>true</code>. - * + * * @see DeploymentConfiguration#isXsrfProtectionEnabled() - * + * * @since 7.1 - * + * * @param session * the vaadin session for which the check should be done * @param requestToken @@ -1712,15 +1708,15 @@ public abstract class VaadinService implements Serializable { * Implementation for {@link VaadinSession#access(Runnable)}. This method is * implemented here instead of in {@link VaadinSession} to enable overriding * the implementation without using a custom subclass of VaadinSession. - * + * * @since 7.1 * @see VaadinSession#access(Runnable) - * + * * @param session * the vaadin session to access * @param runnable * the runnable to run with the session locked - * + * * @return a future that can be used to check for task completion and to * cancel the task */ @@ -1739,7 +1735,7 @@ public abstract class VaadinService implements Serializable { * thread, the queue will be purged when the session is unlocked. If the * lock is not held by any thread, it is acquired and the queue is purged * right away. - * + * * @since 7.1.2 * @param session * the session for which the access queue should be purged @@ -1775,7 +1771,7 @@ public abstract class VaadinService implements Serializable { * <p> * This method is automatically run by the framework at appropriate * situations and is not intended to be used by application developers. - * + * * @param session * the vaadin session to purge the queue for * @since 7.1 @@ -1817,11 +1813,11 @@ public abstract class VaadinService implements Serializable { /** * Adds a service destroy listener that gets notified when this service is * destroyed. - * + * * @since 7.2 * @param listener * the service destroy listener to add - * + * * @see #destroy() * @see #removeServiceDestroyListener(ServiceDestroyListener) * @see ServiceDestroyListener @@ -1834,7 +1830,7 @@ public abstract class VaadinService implements Serializable { /** * Removes a service destroy listener that was previously added with * {@link #addServiceDestroyListener(ServiceDestroyListener)}. - * + * * @since 7.2 * @param listener * the service destroy listener to remove @@ -1848,11 +1844,11 @@ public abstract class VaadinService implements Serializable { * Called when the servlet, portlet or similar for this service is being * destroyed. After this method has been called, no more requests will be * handled by this service. - * + * * @see #addServiceDestroyListener(ServiceDestroyListener) * @see Servlet#destroy() * @see Portlet#destroy() - * + * * @since 7.2 */ public void destroy() { diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 12e7c28cd8..09b8a22a46 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -16,12 +16,14 @@ package com.vaadin.server; import java.io.BufferedWriter; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.io.Serializable; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; @@ -29,7 +31,10 @@ import java.net.URLConnection; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,6 +56,59 @@ import com.vaadin.util.CurrentInstance; @SuppressWarnings("serial") public class VaadinServlet extends HttpServlet implements Constants { + private static class ScssCacheEntry implements Serializable { + + private final String css; + private final List<String> sourceUris; + private final long timestamp; + + public ScssCacheEntry(String css, List<String> sourceUris) { + this.css = css; + this.sourceUris = sourceUris; + + timestamp = getLastModified(); + } + + public String getCss() { + return css; + } + + private long getLastModified() { + long newest = 0; + for (String uri : sourceUris) { + File file = new File(uri); + if (!file.exists()) { + return -1; + } else { + newest = Math.max(newest, file.lastModified()); + } + } + + return newest; + } + + public boolean isStillValid() { + if (timestamp == -1) { + /* + * Don't ever bother checking anything if files used during the + * compilation were gone before the cache entry was created. + */ + return false; + } else if (timestamp != getLastModified()) { + /* + * Would in theory still be valid if the last modification is + * before the recorded timestamp, but that would still mean that + * something has changed since we last checked, so let's + * invalidate in that case as well to be on the safe side. + */ + return false; + } else { + return true; + } + } + + } + private VaadinServletService servletService; /** @@ -535,10 +593,18 @@ public class VaadinServlet extends HttpServlet implements Constants { * Mutex for preventing to scss compilations to take place simultaneously. * This is a workaround needed as the scss compiler currently is not thread * safe (#10292). + * <p> + * In addition, this is also used to protect the cached compilation results. */ private static final Object SCSS_MUTEX = new Object(); /** + * Global cache of scss compilation results. This map is protected from + * concurrent access by {@link #SCSS_MUTEX}. + */ + private static final Map<String, ScssCacheEntry> scssCache = new HashMap<String, ScssCacheEntry>(); + + /** * Returns the default theme. Must never return null. * * @return @@ -824,46 +890,62 @@ public class VaadinServlet extends HttpServlet implements Constants { } synchronized (SCSS_MUTEX) { - String realFilename = sc.getRealPath(scssFilename); - ScssStylesheet scss = ScssStylesheet.get(realFilename); - if (scss == null) { - // Not a file in the file system (WebContent directory). Use the - // identifier directly (VAADIN/themes/.../styles.css) so - // ScssStylesheet will try using the class loader. - if (scssFilename.startsWith("/")) { - scssFilename = scssFilename.substring(1); - } + ScssCacheEntry cacheEntry = scssCache.get(scssFilename); - scss = ScssStylesheet.get(scssFilename); + if (cacheEntry == null || !cacheEntry.isStillValid()) { + cacheEntry = compileScssOnTheFly(filename, scssFilename, sc); + scssCache.put(scssFilename, cacheEntry); } - if (scss == null) { - getLogger() - .log(Level.WARNING, - "Scss file {0} exists but ScssStylesheet was not able to find it", - scssFilename); - return false; - } - try { - getLogger().log(Level.FINE, "Compiling {0} for request to {1}", - new Object[] { realFilename, filename }); - scss.compile(); - } catch (Exception e) { - getLogger().log(Level.WARNING, "Scss compilation failed", e); + if (cacheEntry == null) { + // compilation did not produce any result, but logged a message return false; } // This is for development mode only so instruct the browser to - // never - // cache it + // never cache it response.setHeader("Cache-Control", "no-cache"); final String mimetype = getService().getMimeType(filename); - writeResponse(response, mimetype, scss.printState()); + writeResponse(response, mimetype, cacheEntry.getCss()); return true; } } + private ScssCacheEntry compileScssOnTheFly(String filename, + String scssFilename, ServletContext sc) throws IOException { + String realFilename = sc.getRealPath(scssFilename); + ScssStylesheet scss = ScssStylesheet.get(realFilename); + if (scss == null) { + // Not a file in the file system (WebContent directory). Use the + // identifier directly (VAADIN/themes/.../styles.css) so + // ScssStylesheet will try using the class loader. + if (scssFilename.startsWith("/")) { + scssFilename = scssFilename.substring(1); + } + + scss = ScssStylesheet.get(scssFilename); + } + + if (scss == null) { + getLogger() + .log(Level.WARNING, + "Scss file {0} exists but ScssStylesheet was not able to find it", + scssFilename); + return null; + } + try { + getLogger().log(Level.FINE, "Compiling {0} for request to {1}", + new Object[] { realFilename, filename }); + scss.compile(); + } catch (Exception e) { + getLogger().log(Level.WARNING, "Scss compilation failed", e); + return null; + } + + return new ScssCacheEntry(scss.printState(), scss.getSourceUris()); + } + /** * Check whether a URL obtained from a classloader refers to a valid static * resource in the directory VAADIN. diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java index bbabd881f8..f93cb8e070 100644 --- a/server/src/com/vaadin/server/VaadinSession.java +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -65,7 +65,7 @@ import com.vaadin.util.ReflectTools; * Everything inside a {@link VaadinSession} should be serializable to ensure * compatibility with schemes using serialization for persisting the session * data. - * + * * @author Vaadin Ltd * @since 7.0.0 */ @@ -77,7 +77,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * {@link VaadinSession#access(Runnable)}. This class is used internally by * the framework and is not intended to be directly used by application * developers. - * + * * @since 7.1 * @author Vaadin Ltd */ @@ -93,10 +93,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Creates an instance for the given runnable - * + * * @param session * the session to which the task belongs - * + * * @param runnable * the runnable to run when this task is purged from the * queue @@ -126,9 +126,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the current instance values that should be used when running * this task. - * + * * @see CurrentInstance#restoreInstances(Map) - * + * * @return a map of current instances. */ public Map<Class<?>, CurrentInstance> getCurrentInstances() { @@ -137,7 +137,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Handles exceptions thrown during the execution of this task. - * + * * @since 7.1.8 * @param exception * the thrown exception. @@ -168,7 +168,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * The lifecycle state of a VaadinSession. - * + * * @since 7.2 */ public enum State { @@ -273,7 +273,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Creates a new VaadinSession tied to a VaadinService. - * + * * @param service * the Vaadin service for the new session */ @@ -327,9 +327,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Get the web browser associated with this session. - * + * * @return the web browser object - * + * * @deprecated As of 7.0, use {@link Page#getWebBrowser()} instead. */ @Deprecated @@ -350,7 +350,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Sets the time spent servicing the last request in the session and updates * the total time spent servicing requests in this session. - * + * * @param time * The time spent in the last request, in milliseconds. */ @@ -371,11 +371,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Sets the time when the last UIDL request was serviced in this session. - * + * * @param timestamp * The time when the last request was handled, in milliseconds * since the epoch. - * + * */ public void setLastRequestTimestamp(long timestamp) { assert hasLock(); @@ -384,7 +384,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Returns the time when the last request was serviced in this session. - * + * * @return The time when the last request was handled, in milliseconds since * the epoch. */ @@ -396,7 +396,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the underlying session to which this service session is currently * associated. - * + * * @return the wrapped session for this context */ public WrappedSession getSession() { @@ -410,7 +410,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * @return - * + * * @deprecated As of 7.0. Will likely change or be removed in a future * version */ @@ -430,7 +430,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Loads the VaadinSession for the given service and WrappedSession from the * HTTP session. - * + * * @param service * The service the VaadinSession is associated with * @param underlyingSession @@ -460,7 +460,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Retrieves all {@link VaadinSession}s which are stored in the given HTTP * session - * + * * @since 7.2 * @param httpSession * the HTTP session @@ -485,7 +485,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Removes this VaadinSession from the HTTP session. - * + * * @param service * The service this session is associated with * @deprecated As of 7.0. Should be moved to a separate session storage @@ -500,7 +500,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Retrieves the name of the attribute used for storing a VaadinSession for * the given service. - * + * * @param service * The service associated with the sessio * @return The attribute name used for storing the session @@ -511,7 +511,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Stores this VaadinSession in the HTTP session. - * + * * @param service * The service this session is associated with * @param session @@ -564,7 +564,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the configuration for this session - * + * * @return the deployment configuration */ public DeploymentConfiguration getConfiguration() { @@ -574,10 +574,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the default locale for this session. - * + * * By default this is the preferred locale of the user using the session. In * most cases it is read from the browser defaults. - * + * * @return the locale of this session. */ public Locale getLocale() { @@ -590,13 +590,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Sets the default locale for this session. - * + * * By default this is the preferred locale of the user using the * application. In most cases it is read from the browser defaults. - * + * * @param locale * the Locale object. - * + * */ public void setLocale(Locale locale) { assert hasLock(); @@ -605,7 +605,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the session's error handler. - * + * * @return the current error handler */ public ErrorHandler getErrorHandler() { @@ -615,7 +615,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Sets the session error handler. - * + * * @param errorHandler */ public void setErrorHandler(ErrorHandler errorHandler) { @@ -626,9 +626,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the {@link ConverterFactory} used to locate a suitable * {@link Converter} for fields in the session. - * + * * See {@link #setConverterFactory(ConverterFactory)} for more details - * + * * @return The converter factory used in the session */ public ConverterFactory getConverterFactory() { @@ -653,7 +653,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * </p> * <p> * The converter factory must never be set to null. - * + * * @param converterFactory * The converter factory used in the session */ @@ -670,12 +670,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Handlers are called in reverse order of addition, so the most recently * added handler will be called first. * </p> - * + * * @param handler * the request handler to add - * + * * @see #removeRequestHandler(RequestHandler) - * + * * @since 7.0 */ public void addRequestHandler(RequestHandler handler) { @@ -685,10 +685,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Removes a request handler from the session. - * + * * @param handler * the request handler to remove - * + * * @since 7.0 */ public void removeRequestHandler(RequestHandler handler) { @@ -700,13 +700,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Gets the request handlers that are registered to the session. The * iteration order of the returned collection is the same as the order in * which the request handlers will be invoked when a request is handled. - * + * * @return a collection of request handlers, with the iteration order * according to the order they would be invoked - * + * * @see #addRequestHandler(RequestHandler) * @see #removeRequestHandler(RequestHandler) - * + * * @since 7.0 */ public Collection<RequestHandler> getRequestHandlers() { @@ -721,12 +721,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * {@link InheritableThreadLocal}). In other cases, (e.g. from background * threads started in some other way), the current session is not * automatically defined. - * + * * @return the current session instance if available, otherwise * <code>null</code> - * + * * @see #setCurrent(VaadinSession) - * + * * @since 7.0 */ public static VaadinSession getCurrent() { @@ -742,12 +742,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * session outside the normal request handling and treads started from * request handling threads, e.g. when initiating custom background threads. * </p> - * + * * @param session - * + * * @see #getCurrent() * @see ThreadLocal - * + * * @since 7.0 */ public static void setCurrent(VaadinSession session) { @@ -758,9 +758,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Gets all the UIs of this session. This includes UIs that have been * requested but not yet initialized. UIs that receive no heartbeat requests * from the client are eventually removed from the session. - * + * * @return a collection of UIs belonging to this application - * + * * @since 7.0 */ public Collection<UI> getUIs() { @@ -775,11 +775,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Generate an id for the given Connector. Connectors must not call this * method more than once, the first time they need an id. - * + * * @param connector * A connector that has not yet been assigned an id. * @return A new id for the connector - * + * * @deprecated As of 7.0. Will likely change or be removed in a future * version */ @@ -794,7 +794,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * <p> * This is meant for framework internal use. * </p> - * + * * @param uiId * The UI id * @return The UI with the given id or null if not found @@ -806,7 +806,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Checks if the current thread has exclusive access to this VaadinSession - * + * * @return true if the thread has exclusive access, false otherwise */ public boolean hasLock() { @@ -817,7 +817,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Checks if the current thread has exclusive access to the given * WrappedSession. - * + * * @return true if this thread has exclusive access, false otherwise */ private static boolean hasLock(VaadinService service, WrappedSession session) { @@ -830,10 +830,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * be generated. This can be used to modify the contents of the HTML that * loads the Vaadin application in the browser and the HTTP headers that are * included in the response serving the HTML. - * + * * @see BootstrapListener#modifyBootstrapFragment(BootstrapFragmentResponse) * @see BootstrapListener#modifyBootstrapPage(BootstrapPageResponse) - * + * * @param listener * the bootstrap listener to add */ @@ -847,9 +847,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Remove a bootstrap listener that was previously added. - * + * * @see #addBootstrapListener(BootstrapListener) - * + * * @param listener * the bootstrap listener to remove */ @@ -865,11 +865,11 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Fires a bootstrap event to all registered listeners. There are currently * two supported events, both inheriting from {@link BootstrapResponse}: * {@link BootstrapFragmentResponse} and {@link BootstrapPageResponse}. - * + * * @param response * the bootstrap response event for which listeners should be * fired - * + * * @deprecated As of 7.0. Will likely change or be removed in a future * version */ @@ -882,12 +882,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Called by the framework to remove an UI instance from the session because * it has been closed. - * + * * @param ui * the UI to remove */ public void removeUI(UI ui) { assert hasLock(); + assert UI.getCurrent() == ui; Integer id = Integer.valueOf(ui.getUIId()); ui.setSession(null); uIs.remove(id); @@ -902,7 +903,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * connector resources that are not served by any single connector because * e.g. because they are served with strong caching or because of legacy * reasons. - * + * * @param createOnDemand * <code>true</code> if a resource handler should be initialized * if there is no handler associated with this application. @@ -911,7 +912,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * @return this session's global resource handler, or <code>null</code> if * there is no handler and the createOnDemand parameter is * <code>false</code>. - * + * * @since 7.0.0 */ public GlobalResourceHandler getGlobalResourceHandler(boolean createOnDemand) { @@ -933,10 +934,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * instance is not guaranteed to support any other features of the * <code>Lock</code> interface than {@link Lock#lock()} and * {@link Lock#unlock()}. - * + * * @return the <code>Lock</code> that is used for synchronization, never * <code>null</code> - * + * * @see #lock() * @see Lock */ @@ -951,7 +952,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * is done correctly is to wrap your code using {@link UI#access(Runnable)} * (or {@link VaadinSession#access(Runnable)} if you are only touching the * session and not any UI), e.g.: - * + * * <pre> * myUI.access(new Runnable() { * @Override @@ -962,10 +963,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * } * }); * </pre> - * + * * If you for whatever reason want to do locking manually, you should do it * like: - * + * * <pre> * session.lock(); * try { @@ -974,12 +975,12 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * session.unlock(); * } * </pre> - * + * * This method will block until the lock can be retrieved. * <p> * {@link #getLockInstance()} can be used if more control over the locking * is required. - * + * * @see #unlock() * @see #getLockInstance() * @see #hasLock() @@ -995,7 +996,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * For UIs in this session that have its push mode set to * {@link PushMode#AUTOMATIC automatic}, pending changes will be pushed to * their respective clients. - * + * * @see #lock() * @see UI#push() */ @@ -1045,9 +1046,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * data with the current user so that it can be retrieved at a later point * from some other part of the application. Setting the value to * <code>null</code> clears the stored value. - * + * * @see #getAttribute(String) - * + * * @param name * the name to associate the value with, can not be * <code>null</code> @@ -1077,10 +1078,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * value. The outcome of calling this method is thus the same as if calling<br /> * <br /> * <code>setAttribute(type.getName(), value);</code> - * + * * @see #getAttribute(Class) * @see #setAttribute(String, Object) - * + * * @param type * the type that the stored value represents, can not be null * @param value @@ -1104,9 +1105,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Gets a stored attribute value. If a value has been stored for the * session, that value is returned. If no value is stored for the name, * <code>null</code> is returned. - * + * * @see #setAttribute(String, Object) - * + * * @param name * the name of the value to get, can not be <code>null</code>. * @return the value, or <code>null</code> if no value has been stored or if @@ -1129,10 +1130,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * value. The outcome of calling this method is thus the same as if calling<br /> * <br /> * <code>getAttribute(type.getName());</code> - * + * * @see #setAttribute(Class, Object) * @see #getAttribute(String) - * + * * @param type * the type of the value to get, can not be <code>null</code>. * @return the value, or <code>null</code> if no value has been stored or if @@ -1153,7 +1154,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Creates a new unique id for a UI. - * + * * @return a unique UI id */ public int getNextUIid() { @@ -1163,7 +1164,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Adds an initialized UI to this session. - * + * * @param ui * the initialized UI to add. */ @@ -1197,7 +1198,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Adds a UI provider to this session. - * + * * @param uiProvider * the UI provider that should be added */ @@ -1208,7 +1209,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Removes a UI provider association from this session. - * + * * @param uiProvider * the UI provider that should be removed */ @@ -1219,7 +1220,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the UI providers configured for this session. - * + * * @return an unmodifiable list of UI providers */ public List<UIProvider> getUIProviders() { @@ -1243,9 +1244,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * To avoid causing out of sync errors, you should typically redirect to * some other page using {@link Page#setLocation(String)} to make the * browser unload the invalidated UI. - * + * * @see SystemMessages#getSessionExpiredCaption() - * + * */ public void close() { assert hasLock(); @@ -1255,13 +1256,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Returns whether this session is marked to be closed. Note that this * method also returns true if the session is actually already closed. - * + * * @see #close() - * + * * @deprecated As of 7.2, use * <code>{@link #getState() getState() != State.OPEN}</code> * instead. - * + * * @return true if this session is marked to be closed, false otherwise */ @Deprecated @@ -1272,7 +1273,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Returns the lifecycle state of this session. - * + * * @since 7.2 * @return the current state */ @@ -1284,7 +1285,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Sets the lifecycle state of this session. The allowed transitions are * OPEN to CLOSING and CLOSING to CLOSED. - * + * * @since 7.2 * @param state * the new state @@ -1323,15 +1324,15 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * later point in time.</li> * </ul> * </p> - * + * * @param runnable * the runnable which accesses the session - * + * * @throws IllegalStateException * if the current thread holds the lock for another session - * + * * @since 7.1 - * + * * @see #lock() * @see #getCurrent() * @see #access(Runnable) @@ -1385,14 +1386,14 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * an exception if it is detected that the current thread holds the lock for * some other session. * </p> - * + * * @see #lock() * @see #getCurrent() * @see #accessSynchronously(Runnable) * @see UI#access(Runnable) - * + * * @since 7.1 - * + * * @param runnable * the runnable which accesses the session * @return a future that can be used to check for task completion and to @@ -1406,9 +1407,9 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { * Gets the queue of tasks submitted using {@link #access(Runnable)}. It is * safe to call this method and access the returned queue without holding * the {@link #lock() session lock}. - * + * * @since 7.1 - * + * * @return the queue of pending access tasks */ public Queue<FutureAccess> getPendingAccessQueue() { @@ -1418,7 +1419,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Gets the CSRF token (aka double submit cookie) that is used to protect * against Cross Site Request Forgery attacks. - * + * * @since 7.1 * @return the csrf token string */ @@ -1439,13 +1440,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { /** * Finds the UI with the corresponding embed id. - * + * * @since 7.2 * @param embedId * the embed id * @return the UI with the corresponding embed id, or <code>null</code> if * no UI is found - * + * * @see UI#getEmbedId() */ public UI getUIByEmbedId(String embedId) { diff --git a/server/src/com/vaadin/server/communication/ClientRpcWriter.java b/server/src/com/vaadin/server/communication/ClientRpcWriter.java index 181bfbb882..1090fdbab9 100644 --- a/server/src/com/vaadin/server/communication/ClientRpcWriter.java +++ b/server/src/com/vaadin/server/communication/ClientRpcWriter.java @@ -81,9 +81,9 @@ public class ClientRpcWriter implements Serializable { // + parameterType.getName()); // } // } - EncodeResult encodeResult = JsonCodec.encode(invocation.getParameters()[i], - referenceParameter, parameterType, - ui.getConnectorTracker()); + EncodeResult encodeResult = JsonCodec.encode( + invocation.getParameters()[i], referenceParameter, + parameterType, ui.getConnectorTracker()); paramJson.put(encodeResult.getEncodedValue()); } invocationJson.put(paramJson); diff --git a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java b/server/src/com/vaadin/server/communication/LegacyUidlWriter.java index 43ea1aca67..3f70a25c5b 100644 --- a/server/src/com/vaadin/server/communication/LegacyUidlWriter.java +++ b/server/src/com/vaadin/server/communication/LegacyUidlWriter.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -35,7 +35,7 @@ import com.vaadin.ui.UI; /** * Serializes legacy UIDL changes to JSON. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -44,7 +44,7 @@ public class LegacyUidlWriter implements Serializable { /** * Writes a JSON array containing the changes of all dirty * {@link LegacyComponent}s in the given UI. - * + * * @param ui * The {@link UI} whose legacy changes to write * @param writer @@ -60,7 +60,8 @@ public class LegacyUidlWriter implements Serializable { Collection<ClientConnector> dirtyVisibleConnectors = ui .getConnectorTracker().getDirtyVisibleConnectors(); - List<Component> legacyComponents = new ArrayList<Component>(); + List<Component> legacyComponents = new ArrayList<Component>( + dirtyVisibleConnectors.size()); for (ClientConnector connector : dirtyVisibleConnectors) { // All Components that want to use paintContent must implement // LegacyComponent diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index 983ada3279..67e5f87153 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -18,6 +18,7 @@ package com.vaadin.server.communication; import java.io.IOException; import java.io.Reader; +import java.util.Collection; import java.util.logging.Level; import java.util.logging.Logger; @@ -70,9 +71,10 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { AtmosphereRequest req = resource.getRequest(); if (req.getMethod().equalsIgnoreCase("GET")) { - callWithUi(resource, establishCallback); + callWithUi(resource, establishCallback, false); } else if (req.getMethod().equalsIgnoreCase("POST")) { - callWithUi(resource, receiveCallback); + callWithUi(resource, receiveCallback, + resource.transport() == TRANSPORT.WEBSOCKET); } } @@ -199,18 +201,27 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { * the atmosphere resource for the current request * @param callback * the push callback to call when a UI is found and locked + * @param websocket + * true if this is a websocket message (as opposed to a HTTP + * request) */ private void callWithUi(final AtmosphereResource resource, - final PushEventCallback callback) { + final PushEventCallback callback, boolean websocket) { AtmosphereRequest req = resource.getRequest(); VaadinServletRequest vaadinRequest = new VaadinServletRequest(req, service); VaadinSession session = null; - service.requestStart(vaadinRequest, null); + if (websocket) { + // For any HTTP request we have already started the request in the + // servlet + service.requestStart(vaadinRequest, null); + } try { try { session = service.findVaadinSession(vaadinRequest); + assert VaadinSession.getCurrent() == session; + } catch (ServiceException e) { getLogger().log(Level.SEVERE, "Could not get session. This should never happen", e); @@ -231,9 +242,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { UI ui = null; session.lock(); try { - VaadinSession.setCurrent(session); - // Sets UI.currentInstance ui = service.findUI(vaadinRequest); + assert UI.getCurrent() == ui; + if (ui == null) { sendNotificationAndDisconnect(resource, UidlRequestHandler.getUINotFoundErrorJSON(service, @@ -276,7 +287,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { } } finally { try { - service.requestEnd(vaadinRequest, null, session); + if (websocket) { + service.requestEnd(vaadinRequest, null, session); + } } catch (Exception e) { getLogger().log(Level.WARNING, "Error while ending request", e); @@ -355,9 +368,31 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { // Sets UI.currentInstance ui = service.findUI(vaadinRequest); if (ui == null) { - getLogger().log(Level.SEVERE, - "Could not get UI. This should never happen"); - return; + /* + * UI not found, could be because FF has asynchronously closed + * the websocket connection and Atmosphere has already done + * cleanup of the request attributes. + * + * In that case, we still have a chance of finding the right UI + * by iterating through the UIs in the session looking for one + * using the same AtmosphereResource. + */ + ui = findUiUsingResource(resource, session.getUIs()); + + if (ui == null) { + getLogger() + .log(Level.SEVERE, + "Could not get UI. This should never happen," + + " except when reloading in Firefox -" + + " see http://dev.vaadin.com/ticket/14251."); + return; + } else { + getLogger() + .log(Level.INFO, + "No UI was found based on data in the request," + + " but a slower lookup based on the AtmosphereResource succeeded." + + " See http://dev.vaadin.com/ticket/14251 for more details."); + } } PushMode pushMode = ui.getPushConfiguration().getPushMode(); @@ -409,6 +444,19 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { } } + private static UI findUiUsingResource(AtmosphereResource resource, + Collection<UI> uIs) { + for (UI ui : uIs) { + PushConnection pushConnection = ui.getPushConnection(); + if (pushConnection instanceof AtmospherePushConnection) { + if (((AtmospherePushConnection) pushConnection).getResource() == resource) { + return ui; + } + } + } + return null; + } + /** * Sends a refresh message to the given atmosphere resource. Uses an * AtmosphereResource instead of an AtmospherePushConnection even though it diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/com/vaadin/server/communication/PushRequestHandler.java index db14e73c1a..308f94686f 100644 --- a/server/src/com/vaadin/server/communication/PushRequestHandler.java +++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -47,7 +47,7 @@ import com.vaadin.shared.communication.PushConstants; * Handles requests to open a push (bidirectional) communication channel between * the client and the server. After the initial request, communication through * the push channel is managed by {@link PushHandler}. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -66,7 +66,8 @@ public class PushRequestHandler implements RequestHandler, public PushRequestHandler(VaadinServletService service) throws ServiceException { - final ServletConfig config = service.getServlet().getServletConfig(); + final ServletConfig vaadinServletConfig = service.getServlet() + .getServletConfig(); atmosphere = new AtmosphereFramework() { @Override @@ -77,7 +78,7 @@ public class PushRequestHandler implements RequestHandler, @Override public AtmosphereFramework addInitParameter(String name, String value) { - if (config.getInitParameter(name) == null) { + if (vaadinServletConfig.getInitParameter(name) == null) { super.addInitParameter(name, value); } return this; @@ -117,7 +118,7 @@ public class PushRequestHandler implements RequestHandler, "org.atmosphere.cpr.showSupportMessage", "false"); try { - atmosphere.init(config); + atmosphere.init(vaadinServletConfig); // Ensure the client-side knows how to split the message stream // into individual messages when using certain transports diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java index 36bfc8bcc6..9107a4e049 100644 --- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java +++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -55,7 +55,7 @@ import com.vaadin.ui.UI; /** * Handles a client-to-server message containing serialized {@link ServerRpc * server RPC} invocations. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -64,7 +64,7 @@ public class ServerRpcHandler implements Serializable { /** * A data transfer object representing an RPC request sent by the client * side. - * + * * @since 7.2 * @author Vaadin Ltd */ @@ -78,7 +78,13 @@ public class ServerRpcHandler implements Serializable { public RpcRequest(String jsonString, VaadinRequest request) throws JSONException { json = new JSONObject(jsonString); - csrfToken = json.getString(ApplicationConstants.CSRF_TOKEN); + + String csrfToken = json.optString(ApplicationConstants.CSRF_TOKEN); + if (csrfToken.equals("")) { + csrfToken = ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE; + } + this.csrfToken = csrfToken; + if (request.getService().getDeploymentConfiguration() .isSyncIdCheckEnabled()) { syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID); @@ -91,7 +97,7 @@ public class ServerRpcHandler implements Serializable { /** * Gets the CSRF security token (double submit cookie) for this request. - * + * * @return the CSRF security token for this current change request */ public String getCsrfToken() { @@ -100,7 +106,7 @@ public class ServerRpcHandler implements Serializable { /** * Gets the data to recreate the RPC as requested by the client side. - * + * * @return the data describing which RPC should be made, and all their * data */ @@ -110,7 +116,7 @@ public class ServerRpcHandler implements Serializable { /** * Gets the sync id last seen by the client. - * + * * @return the last sync id given by the server, according to the * client's request */ @@ -124,9 +130,9 @@ public class ServerRpcHandler implements Serializable { * <p> * <em>Note:</em> This is a shared reference - any modifications made * will be shared. - * + * * @return the raw JSON object that was received from the client - * + * */ public JSONObject getRawJson() { return json; @@ -138,7 +144,7 @@ public class ServerRpcHandler implements Serializable { /** * Reads JSON containing zero or more serialized RPC calls (including legacy * variable changes) and executes the calls. - * + * * @param ui * The {@link UI} receiving the calls. Cannot be null. * @param reader @@ -188,7 +194,7 @@ public class ServerRpcHandler implements Serializable { * changeVariables() is only called once for them. This preserves the Vaadin * 6 semantics for components and add-ons that do not use Vaadin 7 RPC * directly. - * + * * @param uI * the UI receiving the invocations data * @param lastSyncIdSeenByClient @@ -318,7 +324,7 @@ public class ServerRpcHandler implements Serializable { /** * Parse JSON from the client into a list of MethodInvocation instances. - * + * * @param connectorTracker * The ConnectorTracker used to lookup connectors * @param invocationsJson @@ -333,11 +339,13 @@ public class ServerRpcHandler implements Serializable { private List<MethodInvocation> parseInvocations( ConnectorTracker connectorTracker, JSONArray invocationsJson, int lastSyncIdSeenByClient) throws JSONException { - ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>(); + int invocationCount = invocationsJson.length(); + ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>( + invocationCount); MethodInvocation previousInvocation = null; // parse JSON to MethodInvocations - for (int i = 0; i < invocationsJson.length(); ++i) { + for (int i = 0; i < invocationCount; ++i) { JSONArray invocationJson = invocationsJson.getJSONArray(i); @@ -500,7 +508,7 @@ public class ServerRpcHandler implements Serializable { /** * Generates an error message when the client is trying to to something * ('what') with a connector which is disabled or invisible. - * + * * @since 7.1.8 * @param connector * the connector which is disabled (or invisible) diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 9dbd9a093d..c9639813ca 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -37,6 +37,7 @@ import com.vaadin.server.VaadinSession; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.ComponentConstants; import com.vaadin.shared.ui.ComponentStateUtil; +import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Field.ValueChangeEvent; import com.vaadin.util.ReflectTools; @@ -45,7 +46,7 @@ import com.vaadin.util.ReflectTools; * {@link Component} interface. Basic UI components that are not derived from an * external component can inherit this class to easily qualify as Vaadin * components. Most components in Vaadin do just that. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -83,7 +84,7 @@ public abstract class AbstractComponent extends AbstractClientConnector private Unit widthUnit = Unit.PIXELS; private Unit heightUnit = Unit.PIXELS; private static final Pattern sizePattern = Pattern - .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$"); + .compile(SharedUtil.SIZE_PATTERN); /** * Keeps track of the Actions added to this component; the actual @@ -240,7 +241,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * Sets the component's caption <code>String</code>. Caption is the visible * name of the component. This method will trigger a * {@link RepaintRequestEvent}. - * + * * @param caption * the new caption <code>String</code> for the component. */ @@ -271,7 +272,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the locale of this component. - * + * * <pre> * // Component for which the locale is meaningful * InlineDateField date = new InlineDateField("Datum"); @@ -283,8 +284,8 @@ public abstract class AbstractComponent extends AbstractClientConnector * date.setResolution(DateField.RESOLUTION_DAY); * layout.addComponent(date); * </pre> - * - * + * + * * @param locale * the locale to become this component's locale. */ @@ -310,7 +311,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's icon. This method will trigger a * {@link RepaintRequestEvent}. - * + * * @param icon * the icon to be shown with the component's caption. */ @@ -376,7 +377,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's immediate mode to the specified status. - * + * * @param immediate * the boolean value specifying if the component should be in the * immediate mode after the call. @@ -437,11 +438,11 @@ public abstract class AbstractComponent extends AbstractClientConnector * Sets the component's description. See {@link #getDescription()} for more * information on what the description is. This method will trigger a * {@link RepaintRequestEvent}. - * + * * The description is displayed as HTML in tooltips or directly in certain * components so care should be taken to avoid creating the possibility for * HTML injection and possibly XSS vulnerabilities. - * + * * @param description * the new description string for the component. */ @@ -490,7 +491,7 @@ public abstract class AbstractComponent extends AbstractClientConnector * To find the Window that contains the component, use {@code Window w = * getParent(Window.class);} * </p> - * + * * @param <T> * The type of the ancestor * @param parentType @@ -511,7 +512,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the error message for this component. - * + * * @return ErrorMessage containing the description of the error state of the * component or null, if the component contains no errors. Extending * classes should override this method if they support other error @@ -524,9 +525,9 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the component's error message. - * + * * @link Terminal.ErrorMessage#ErrorMessage(String, int) - * + * * @return the component's error message. */ public ErrorMessage getComponentError() { @@ -536,9 +537,9 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the component's error message. The message may contain certain XML * tags, for more information see - * + * * @link Component.ErrorMessage#ErrorMessage(String, int) - * + * * @param componentError * the new <code>ErrorMessage</code> of the component. */ @@ -615,7 +616,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Build CSS compatible string representation of height. - * + * * @return CSS height */ private String getCSSHeight() { @@ -624,7 +625,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Build CSS compatible string representation of width. - * + * * @return CSS width */ private String getCSSWidth() { @@ -634,12 +635,12 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Returns the shared state bean with information to be sent from the server * to the client. - * + * * Subclasses should override this method and set any relevant fields of the * state returned by super.getState(). - * + * * @since 7.0 - * + * * @return updated component shared state */ @Override @@ -730,7 +731,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Sets the data object, that can be used for any application specific data. * The component does not use or modify this data. - * + * * @param data * the Application specific data. * @since 3.1 @@ -741,7 +742,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the application specific data. See {@link #setData(Object)}. - * + * * @return the Application specific data set with setData function. * @since 3.1 */ @@ -916,7 +917,7 @@ public abstract class AbstractComponent extends AbstractClientConnector size = -1; unit = Unit.PIXELS; } else { - String symbol = matcher.group(3); + String symbol = matcher.group(2); unit = Unit.getUnitFromSymbol(symbol); } } else { @@ -951,7 +952,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Gets the {@link ActionManager} used to manage the * {@link ShortcutListener}s added to this {@link Field}. - * + * * @return the ActionManager in use */ protected ActionManager getActionManager() { @@ -995,7 +996,7 @@ public abstract class AbstractComponent extends AbstractClientConnector /** * Determine whether a <code>content</code> component is equal to, or the * ancestor of this component. - * + * * @param content * the potential ancestor element * @return <code>true</code> if the relationship holds diff --git a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java index d6e232035b..f3cbf47b62 100644 --- a/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ b/server/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -116,6 +116,8 @@ import com.vaadin.shared.ui.JavaScriptComponentState; * <li>The primitive Java boolean and the boxed Boolean are represented by * JavaScript booleans.</li> * <li>Java Strings are represented by JavaScript strings.</li> + * <li>Java Dates are represented by JavaScript numbers containing the timestamp + * </li> * <li>List, Set and all arrays in Java are represented by JavaScript arrays.</li> * <li>Map<String, ?> in Java is represented by JavaScript object with fields * corresponding to the map keys.</li> diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java index b8db329906..b083db3183 100644 --- a/server/src/com/vaadin/ui/AbstractSelect.java +++ b/server/src/com/vaadin/ui/AbstractSelect.java @@ -759,7 +759,9 @@ public abstract class AbstractSelect extends AbstractField<Object> implements */ @Override public int size() { - return items.size(); + int size = items.size(); + assert size >= 0; + return size; } /** diff --git a/server/src/com/vaadin/ui/AbstractTextField.java b/server/src/com/vaadin/ui/AbstractTextField.java index e0318ddf2b..9293d38119 100644 --- a/server/src/com/vaadin/ui/AbstractTextField.java +++ b/server/src/com/vaadin/ui/AbstractTextField.java @@ -147,6 +147,18 @@ public abstract class AbstractTextField extends AbstractField<String> implements try { + // Sets the height set by the user when resize the <textarea>. + String newHeight = (String) variables.get("height"); + if (newHeight != null) { + setHeight(newHeight); + } + + // Sets the width set by the user when resize the <textarea>. + String newWidth = (String) variables.get("width"); + if (newWidth != null) { + setWidth(newWidth); + } + if (variables.containsKey(TextFieldConstants.VAR_CURSOR)) { Integer object = (Integer) variables .get(TextFieldConstants.VAR_CURSOR); diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java index 048726dc84..5367505c56 100644 --- a/server/src/com/vaadin/ui/ComboBox.java +++ b/server/src/com/vaadin/ui/ComboBox.java @@ -354,6 +354,7 @@ public class ComboBox extends AbstractSelect implements if (pageLength == 0) { // no paging: return all items filteredSize = container.size(); + assert filteredSize >= 0; return new ArrayList<Object>(container.getItemIds()); } @@ -391,6 +392,7 @@ public class ComboBox extends AbstractSelect implements } filteredSize = container.size(); + assert filteredSize >= 0; currentPage = adjustCurrentPage(currentPage, needNullSelectOption, indexToEnsureInView, filteredSize); int first = getFirstItemIndexOnCurrentPage(needNullSelectOption, diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index b5a0227d99..9b8729f779 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -55,10 +55,10 @@ import com.vaadin.server.StreamVariable; * operation new information needs to be sent to its * {@link com.vaadin.client.ServerConnector}. * </p> - * + * * @author Vaadin Ltd * @since 7.0.0 - * + * */ public class ConnectorTracker implements Serializable { @@ -87,7 +87,7 @@ public class ConnectorTracker implements Serializable { /** * Map to track on which syncId each connector was removed. - * + * * @see #getCurrentSyncId() * @see #cleanConcurrentlyRemovedConnectorIds(long) */ @@ -95,9 +95,9 @@ public class ConnectorTracker implements Serializable { /** * Gets a logger for this class - * + * * @return A logger instance for logging within this class - * + * */ public static Logger getLogger() { return Logger.getLogger(ConnectorTracker.class.getName()); @@ -107,7 +107,7 @@ public class ConnectorTracker implements Serializable { * Creates a new ConnectorTracker for the given uI. A tracker is always * attached to a uI and the uI cannot be changed during the lifetime of a * {@link ConnectorTracker}. - * + * * @param uI * The uI to attach to. Cannot be null. */ @@ -121,7 +121,7 @@ public class ConnectorTracker implements Serializable { * The lookup method {@link #getConnector(String)} only returns registered * connectors. * </p> - * + * * @param connector * The connector to register. */ @@ -157,12 +157,12 @@ public class ConnectorTracker implements Serializable { /** * Unregister the given connector. - * + * * <p> * The lookup method {@link #getConnector(String)} only returns registered * connectors. * </p> - * + * * @param connector * The connector to unregister */ @@ -213,7 +213,7 @@ public class ConnectorTracker implements Serializable { * Checks whether the given connector has already been initialized in the * browser. The given connector should be registered with this connector * tracker. - * + * * @param connector * the client connector to check * @return <code>true</code> if the initial state has previously been sent @@ -228,9 +228,9 @@ public class ConnectorTracker implements Serializable { /** * Marks the given connector as initialized, meaning that the client-side * state has been initialized for the connector. - * + * * @see #isClientSideInitialized(ClientConnector) - * + * * @param connector * the connector that should be marked as initialized */ @@ -242,7 +242,7 @@ public class ConnectorTracker implements Serializable { * Marks all currently registered connectors as uninitialized. This should * be done when the client-side has been reset but the server-side state is * retained. - * + * * @see #isClientSideInitialized(ClientConnector) */ public void markAllClientSidesUninitialized() { @@ -252,7 +252,7 @@ public class ConnectorTracker implements Serializable { /** * Gets a connector by its id. - * + * * @param connectorId * The connector id to look for * @return The connector with the given id or null if no connector has the @@ -400,10 +400,10 @@ public class ConnectorTracker implements Serializable { /** * Mark the connector as dirty. This should not be done while the response * is being written. - * + * * @see #getDirtyConnectors() * @see #isWritingResponse() - * + * * @param connector * The connector that should be marked clean. */ @@ -425,7 +425,7 @@ public class ConnectorTracker implements Serializable { /** * Mark the connector as clean. - * + * * @param connector * The connector that should be marked clean. */ @@ -443,7 +443,7 @@ public class ConnectorTracker implements Serializable { /** * Returns {@link #getConnectorString(ClientConnector)} for the connector * and its parent (if it has a parent). - * + * * @param connector * The connector * @return A string describing the connector and its parent @@ -460,7 +460,7 @@ public class ConnectorTracker implements Serializable { /** * Returns a string with the connector name and id. Useful mostly for * debugging and logging. - * + * * @param connector * The connector * @return A string that describes the connector @@ -500,7 +500,7 @@ public class ConnectorTracker implements Serializable { /** * Marks all visible connectors dirty, starting from the given connector and * going downwards in the hierarchy. - * + * * @param c * The component to start iterating downwards from */ @@ -521,7 +521,7 @@ public class ConnectorTracker implements Serializable { * The state and pending RPC calls for dirty connectors are sent to the * client in the following request. * </p> - * + * * @return A collection of all dirty connectors for this uI. This list may * contain invisible connectors. */ @@ -531,7 +531,7 @@ public class ConnectorTracker implements Serializable { /** * Checks if there a dirty connectors. - * + * * @return true if there are dirty connectors, false otherwise */ public boolean hasDirtyConnectors() { @@ -541,17 +541,19 @@ public class ConnectorTracker implements Serializable { /** * Returns a collection of those {@link #getDirtyConnectors() dirty * connectors} that are actually visible to the client. - * + * * @return A list of dirty and visible connectors. */ public ArrayList<ClientConnector> getDirtyVisibleConnectors() { - ArrayList<ClientConnector> dirtyConnectors = new ArrayList<ClientConnector>(); - for (ClientConnector c : getDirtyConnectors()) { + Collection<ClientConnector> dirtyConnectors = getDirtyConnectors(); + ArrayList<ClientConnector> dirtyVisibleConnectors = new ArrayList<ClientConnector>( + dirtyConnectors.size()); + for (ClientConnector c : dirtyConnectors) { if (LegacyCommunicationManager.isConnectorVisibleToClient(c)) { - dirtyConnectors.add(c); + dirtyVisibleConnectors.add(c); } } - return dirtyConnectors; + return dirtyVisibleConnectors; } public JSONObject getDiffState(ClientConnector connector) { @@ -571,10 +573,10 @@ public class ConnectorTracker implements Serializable { /** * Checks whether the response is currently being written. Connectors can * not be marked as dirty when a response is being written. - * + * * @see #setWritingResponse(boolean) * @see #markDirty(ClientConnector) - * + * * @return <code>true</code> if the response is currently being written, * <code>false</code> if outside the response writing phase. */ @@ -590,14 +592,14 @@ public class ConnectorTracker implements Serializable { * {@link #getCurrentSyncId()}), if {@link #isWritingResponse()} returns * <code>false</code> and <code>writingResponse</code> is set to * <code>true</code>. - * + * * @param writingResponse * the new response status. - * + * * @see #markDirty(ClientConnector) * @see #isWritingResponse() * @see #getCurrentSyncId() - * + * * @throws IllegalArgumentException * if the new response status is the same as the previous value. * This is done to help detecting problems caused by missed @@ -625,7 +627,7 @@ public class ConnectorTracker implements Serializable { // Convert JSONObjects in diff state to String representation as // JSONObject is not serializable HashMap<ClientConnector, String> stringDiffStates = new HashMap<ClientConnector, String>( - diffStates.size()); + diffStates.size() * 2); for (ClientConnector key : diffStates.keySet()) { stringDiffStates.put(key, diffStates.get(key).toString()); } @@ -643,7 +645,8 @@ public class ConnectorTracker implements Serializable { @SuppressWarnings("unchecked") HashMap<ClientConnector, String> stringDiffStates = (HashMap<ClientConnector, String>) in .readObject(); - diffStates = new HashMap<ClientConnector, JSONObject>(); + diffStates = new HashMap<ClientConnector, JSONObject>( + stringDiffStates.size() * 2); for (ClientConnector key : stringDiffStates.keySet()) { try { diffStates.put(key, new JSONObject(stringDiffStates.get(key))); @@ -657,7 +660,7 @@ public class ConnectorTracker implements Serializable { /** * Checks if the indicated connector has a StreamVariable of the given name * and returns the variable if one is found. - * + * * @param connectorId * @param variableName * @return variable if a matching one exists, otherwise null @@ -678,7 +681,7 @@ public class ConnectorTracker implements Serializable { /** * Adds a StreamVariable of the given name to the indicated connector. - * + * * @param connectorId * @param variableName * @param variable @@ -734,7 +737,7 @@ public class ConnectorTracker implements Serializable { /** * Removes any StreamVariable of the given name from the indicated * connector. - * + * * @param connectorId * @param variableName */ @@ -752,7 +755,7 @@ public class ConnectorTracker implements Serializable { /** * Returns the security key associated with the given StreamVariable. - * + * * @param variable * @return matching security key if one exists, null otherwise */ @@ -767,7 +770,7 @@ public class ConnectorTracker implements Serializable { * Check whether a connector was present on the client when the it was * creating this request, but was removed server-side before the request * arrived. - * + * * @since 7.2 * @param connectorId * The connector id to check for whether it was removed @@ -827,7 +830,7 @@ public class ConnectorTracker implements Serializable { * <p> * The sync id value <code>-1</code> is ignored to facilitate testing with * pre-recorded requests. - * + * * @see #setWritingResponse(boolean) * @see #connectorWasPresentAsRequestWasSent(String, long) * @since 7.2 @@ -853,7 +856,7 @@ public class ConnectorTracker implements Serializable { * <p> * The sync id value <code>-1</code> is ignored to facilitate testing with * pre-recorded requests. - * + * * @see #connectorWasPresentAsRequestWasSent(String, long) * @since 7.2 * @param lastSyncIdSeenByClient diff --git a/server/src/com/vaadin/ui/NotificationConfiguration.java b/server/src/com/vaadin/ui/NotificationConfiguration.java index faab329f88..925c888a51 100644 --- a/server/src/com/vaadin/ui/NotificationConfiguration.java +++ b/server/src/com/vaadin/ui/NotificationConfiguration.java @@ -173,7 +173,8 @@ class NotificationConfigurationImpl implements NotificationConfiguration { NotificationTypeConfiguration styleSetup = getTypeConf(type); if (styleSetup == null) { styleSetup = new NotificationTypeConfiguration(); - ui.getState().notificationConfigurations.put(type.getStyle(), styleSetup); + ui.getState().notificationConfigurations.put(type.getStyle(), + styleSetup); } return styleSetup; diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java index 2fdb3b40a7..8b13ecf1a4 100644 --- a/server/src/com/vaadin/ui/TabSheet.java +++ b/server/src/com/vaadin/ui/TabSheet.java @@ -317,7 +317,8 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * the position at where the the tab should be added. * @return the created {@link Tab} */ - public Tab addTab(Component tabComponent, String caption, Resource icon, int position) { + public Tab addTab(Component tabComponent, String caption, Resource icon, + int position) { if (tabComponent == null) { return null; } else if (tabs.containsKey(tabComponent)) { @@ -1070,8 +1071,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, @Override public Resource getIcon() { - return getResource(ComponentConstants.ICON_RESOURCE - + tabState.key); + return getResource(ComponentConstants.ICON_RESOURCE + tabState.key); } @Override @@ -1211,8 +1211,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, @Override public void setIcon(Resource icon, String iconAltText) { - setResource(ComponentConstants.ICON_RESOURCE + tabState.key, - icon); + setResource(ComponentConstants.ICON_RESOURCE + tabState.key, icon); tabState.iconAltText = iconAltText; } } diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index a8265662ea..84e4eaed13 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -68,7 +68,7 @@ import com.vaadin.shared.ui.table.TableConstants; * <code>Table</code> is used for representing data or components in a pageable * and selectable table. * </p> - * + * * <p> * Scalability of the Table is largely dictated by the container. A table does * not have a limit for the number of items and is just as fast with hundreds of @@ -76,11 +76,11 @@ import com.vaadin.shared.ui.table.TableConstants; * scrolling however limits the number of rows to around 500000, depending on * the browser and the pixel height of rows. * </p> - * + * * <p> * Components in a Table will not have their caption nor icon rendered. * </p> - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -583,7 +583,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new empty table with caption. - * + * * @param caption */ public Table(String caption) { @@ -593,7 +593,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new table with caption and connect it to a Container. - * + * * @param caption * @param dataSource */ @@ -607,11 +607,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the array of visible column id:s, including generated columns. - * + * * <p> * The columns are show in the order of their appearance in this array. * </p> - * + * * @return an array of currently visible propertyIds and generated column * ids. */ @@ -624,11 +624,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the array of visible column property id:s. - * + * * <p> * The columns are show in the order of their appearance in this array. * </p> - * + * * @param visibleColumns * the Array of shown property id:s. */ @@ -690,7 +690,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the headers of the columns. - * + * * <p> * The headers match the property id:s given my the set visible column * headers. The table must be set in either @@ -699,7 +699,7 @@ public class Table extends AbstractSelect implements Action.Container, * headers. In the defaults mode any nulls in the headers array are replaced * with id.toString(). * </p> - * + * * @return the Array of column headers. */ public String[] getColumnHeaders() { @@ -717,7 +717,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the headers of the columns. - * + * * <p> * The headers match the property id:s given my the set visible column * headers. The table must be set in either @@ -726,7 +726,7 @@ public class Table extends AbstractSelect implements Action.Container, * headers. In the defaults mode any nulls in the headers array are replaced * with id.toString() outputs when rendering. * </p> - * + * * @param columnHeaders * the Array of column headers that match the * {@link #getVisibleColumns()} method. @@ -750,7 +750,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the icons of the columns. - * + * * <p> * The icons in headers match the property id:s given my the set visible * column headers. The table must be set in either @@ -758,7 +758,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers * with icons. * </p> - * + * * @return the Array of icons that match the {@link #getVisibleColumns()}. */ public Resource[] getColumnIcons() { @@ -777,7 +777,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the icons of the columns. - * + * * <p> * The icons in headers match the property id:s given my the set visible * column headers. The table must be set in either @@ -785,7 +785,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID} mode to show the headers * with icons. * </p> - * + * * @param columnIcons * the Array of icons that match the {@link #getVisibleColumns()} * . @@ -809,7 +809,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the array of column alignments. - * + * * <p> * The items in the array must match the properties identified by * {@link #getVisibleColumns()}. The possible values for the alignments @@ -822,7 +822,7 @@ public class Table extends AbstractSelect implements Action.Container, * The alignments default to {@link Align#LEFT}: any null values are * rendered as align lefts. * </p> - * + * * @return the Column alignments array. */ public Align[] getColumnAlignments() { @@ -841,7 +841,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column alignments. - * + * * <p> * The amount of items in the array must match the amount of properties * identified by {@link #getVisibleColumns()}. The possible values for the @@ -853,7 +853,7 @@ public class Table extends AbstractSelect implements Action.Container, * </ul> * The alignments default to {@link Align#LEFT} * </p> - * + * * @param columnAlignments * the Column alignments array. */ @@ -882,11 +882,11 @@ public class Table extends AbstractSelect implements Action.Container, * Sets columns width (in pixels). Theme may not necessary respect very * small or very big values. Setting width to -1 (default) means that theme * will make decision of width. - * + * * <p> * Column can either have a fixed width or expand ratio. The latter one set * is used. See @link {@link #setColumnExpandRatio(Object, float)}. - * + * * @param propertyId * colunmns property id * @param width @@ -920,27 +920,27 @@ public class Table extends AbstractSelect implements Action.Container, * naturally. Excess space is the space that is not used by columns with * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural * width (no width nor expand ratio). - * + * * <p> * By default (without expand ratios) the excess space is divided * proportionally to columns natural widths. - * + * * <p> * Only expand ratios of visible columns are used in final calculations. - * + * * <p> * Column can either have a fixed width or expand ratio. The latter one set * is used. - * + * * <p> * A column with expand ratio is considered to be minimum width by default * (if no excess space exists). The minimum width is defined by terminal * implementation. - * + * * <p> * If terminal implementation supports re-sizable columns the column becomes * fixed width column if users resizes the column. - * + * * @param propertyId * columns property id * @param expandRatio @@ -969,7 +969,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the column expand ratio for a columnd. See * {@link #setColumnExpandRatio(Object, float)} - * + * * @param propertyId * columns property id * @return the expandRatio used to divide excess space for this column @@ -984,7 +984,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the pixel width of column - * + * * @param propertyId * @return width of column or -1 when value not set */ @@ -1003,11 +1003,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the page length. - * + * * <p> * Setting page length 0 disables paging. * </p> - * + * * @return the Length of one page. */ public int getPageLength() { @@ -1016,16 +1016,16 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the page length. - * + * * <p> * Setting page length 0 disables paging. The page length defaults to 15. * </p> - * + * * <p> * If Table has width set ({@link #setWidth(float, int)} ) the client side * may update the page length automatically the correct value. * </p> - * + * * @param pageLength * the length of one page. */ @@ -1039,18 +1039,18 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method adjusts a possible caching mechanism of table implementation. - * + * * <p> * Table component may fetch and render some rows outside visible area. With * complex tables (for example containing layouts and components), the * client side may become unresponsive. Setting the value lower, UI will * become more responsive. With higher values scrolling in client will hit * server less frequently. - * + * * <p> * The amount of cached rows will be cacheRate multiplied with pageLength ( * {@link #setPageLength(int)} both below and above visible area.. - * + * * @param cacheRate * a value over 0 (fastest rendering time). Higher value will * cache more rows on server (smoother scrolling). Default value @@ -1069,7 +1069,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * @see #setCacheRate(double) - * + * * @return the current cache rate value */ public double getCacheRate() { @@ -1078,7 +1078,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property currentPageFirstItem. - * + * * @return the Value of property currentPageFirstItem. */ public Object getCurrentPageFirstItemId() { @@ -1106,14 +1106,14 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the item ID for the item represented by the index given. Assumes * that the current container implements {@link Container.Indexed}. - * + * * See {@link Container.Indexed#getIdByIndex(int)} for more information * about the exceptions that can be thrown. - * + * * @param index * the index for which the item ID should be fetched * @return the item ID for the given index - * + * * @throws ClassCastException * if container does not implement {@link Container.Indexed} * @throws IndexOutOfBoundsException @@ -1126,7 +1126,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property currentPageFirstItemId. - * + * * @param currentPageFirstItemId * the New value of property currentPageFirstItemId. */ @@ -1183,7 +1183,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the icon Resource for the specified column. - * + * * @param propertyId * the propertyId indentifying the column. * @return the icon for the specified column; null if the column has no icon @@ -1198,7 +1198,7 @@ public class Table extends AbstractSelect implements Action.Container, * <p> * Throws IllegalArgumentException if the specified column is not visible. * </p> - * + * * @param propertyId * the propertyId identifying the column. * @param icon @@ -1217,7 +1217,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the header for the specified column. - * + * * @param propertyId * the propertyId identifying the column. * @return the header for the specified column if it has one. @@ -1238,7 +1238,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column header for the specified column; - * + * * @param propertyId * the propertyId identifying the column. * @param header @@ -1257,7 +1257,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the specified column's alignment. - * + * * @param propertyId * the propertyID identifying the column. * @return the specified column's alignment if it as one; {@link Align#LEFT} @@ -1270,13 +1270,13 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the specified column's alignment. - * + * * <p> * Throws IllegalArgumentException if the alignment is not one of the * following: {@link Align#LEFT}, {@link Align#CENTER} or * {@link Align#RIGHT} * </p> - * + * * @param propertyId * the propertyID identifying the column. * @param alignment @@ -1296,7 +1296,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if the specified column is collapsed. - * + * * @param propertyId * the propertyID identifying the column. * @return true if the column is collapsed; false otherwise; @@ -1308,8 +1308,8 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether the specified column is collapsed or not. - * - * + * + * * @param propertyId * the propertyID identifying the column. * @param collapsed @@ -1338,7 +1338,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if column collapsing is allowed. - * + * * @return true if columns can be collapsed; false otherwise. */ public boolean isColumnCollapsingAllowed() { @@ -1347,7 +1347,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether column collapsing is allowed or not. - * + * * @param collapsingAllowed * specifies whether column collapsing is allowed. */ @@ -1369,7 +1369,7 @@ public class Table extends AbstractSelect implements Action.Container, * {@link #setColumnCollapsed(Object, boolean) setColumnCollapsed()}) if * {@link #isColumnCollapsingAllowed()} is true. By default all columns are * collapsible. - * + * * @param propertyId * the propertyID identifying the column. * @param collapsible @@ -1391,7 +1391,7 @@ public class Table extends AbstractSelect implements Action.Container, * UI or with {@link #setColumnCollapsed(Object, boolean) * setColumnCollapsed()}) if {@link #isColumnCollapsingAllowed()} is also * true. - * + * * @return true if the column can be collapsed; false otherwise. */ public boolean isColumnCollapsible(Object propertyId) { @@ -1400,7 +1400,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if column reordering is allowed. - * + * * @return true if columns can be reordered; false otherwise. */ public boolean isColumnReorderingAllowed() { @@ -1409,7 +1409,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets whether column reordering is allowed or not. - * + * * @param columnReorderingAllowed * specifies whether column reordering is allowed. */ @@ -1453,7 +1453,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property currentPageFirstItem. - * + * * @return the Value of property currentPageFirstItem. */ public int getCurrentPageFirstItemIndex() { @@ -1513,7 +1513,22 @@ public class Table extends AbstractSelect implements Action.Container, * position not be updated correctly when the lazy rows are * finally rendered. */ - currentPageFirstItemIndexOnLastPage = indexOnLastPage; + + boolean isLastRowPossiblyPartiallyVisible = true; + if (indexOnLastPage != -1) { + /* + * If the requested row was greater than maxIndex, the last + * row should be fully visible (See + * TestCurrentPageFirstItem). + */ + isLastRowPossiblyPartiallyVisible = false; + } + + int extraRows = isLastRowPossiblyPartiallyVisible ? 0 : 1; + currentPageFirstItemIndexOnLastPage = currentPageFirstItemIndex + + extraRows; + } else { + currentPageFirstItemIndexOnLastPage = -1; } } else { @@ -1569,7 +1584,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property currentPageFirstItem. - * + * * @param newIndex * the New value of property currentPageFirstItem. */ @@ -1579,11 +1594,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property selectable. - * + * * <p> * The table is not selectable by default. * </p> - * + * * @return the Value of property selectable. */ public boolean isSelectable() { @@ -1592,11 +1607,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property selectable. - * + * * <p> * The table is not selectable by default. * </p> - * + * * @param selectable * the New value of property selectable. */ @@ -1609,7 +1624,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Getter for property columnHeaderMode. - * + * * @return the Value of property columnHeaderMode. */ public ColumnHeaderMode getColumnHeaderMode() { @@ -1618,7 +1633,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Setter for property columnHeaderMode. - * + * * @param columnHeaderMode * the New value of property columnHeaderMode. */ @@ -1727,7 +1742,7 @@ public class Table extends AbstractSelect implements Action.Container, * occurred exception is set as the cause of this exception. All occurred * exceptions can be accessed using {@link #getCauses()}. * </p> - * + * */ public static class CacheUpdateException extends RuntimeException { private Throwable[] causes; @@ -1751,7 +1766,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the cause(s) for this exception - * + * * @return the exception(s) which caused this exception */ public Throwable[] getCauses() { @@ -1807,11 +1822,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Requests that the Table should be repainted as soon as possible. - * + * * Note that a {@code Table} does not necessarily repaint its contents when * this method has been called. See {@link #refreshRowCache()} for forcing * an update of the contents. - * + * * @deprecated As of 7.0, use {@link #markAsDirty()} instead */ @@ -1823,7 +1838,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Requests that the Table should be repainted as soon as possible. - * + * * Note that a {@code Table} does not necessarily repaint its contents when * this method has been called. See {@link #refreshRowCache()} for forcing * an update of the contents. @@ -2110,9 +2125,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Render rows with index "firstIndex" to "firstIndex+rows-1" to a new * buffer. - * + * * Reuses values from the current page buffer if the rows are found there. - * + * * @param firstIndex * @param rows * @param replaceListeners @@ -2221,7 +2236,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Update a cache array for a row, register any relevant listeners etc. - * + * * This is an internal method extracted from * {@link #getVisibleCellsNoCache(int, int, boolean)} and should be removed * when the Table is rewritten. @@ -2439,7 +2454,7 @@ public class Table extends AbstractSelect implements Action.Container, * Helper method to remove listeners and maintain correct component * hierarchy. Detaches properties and components if those are no more * rendered in client. - * + * * @param oldListenedProperties * set of properties that where listened in last render * @param oldVisibleComponents @@ -2475,12 +2490,12 @@ public class Table extends AbstractSelect implements Action.Container, * if it is a field, it needs to be detached from its property data source * in order to allow garbage collection to take care of removing the unused * component from memory. - * + * * Override this method and getPropertyValue(Object, Object, Property) with * custom logic if you need to deal with buffered fields. - * + * * @see #getPropertyValue(Object, Object, Property) - * + * * @param oldVisibleComponents * a set of components that should be unregistered. */ @@ -2531,7 +2546,7 @@ public class Table extends AbstractSelect implements Action.Container, * </ul> * The default value is {@link #ROW_HEADER_MODE_HIDDEN} * </p> - * + * * @param mode * the One of the modes listed above. */ @@ -2550,7 +2565,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the row header mode. - * + * * @return the Row header mode. * @see #setRowHeaderMode(int) */ @@ -2561,7 +2576,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds the new row to table and fill the visible cells (except generated * columns) with given values. - * + * * @param cells * the Object array that is used for filling the visible cells * new row. The types must be settable to visible column property @@ -2630,7 +2645,7 @@ public class Table extends AbstractSelect implements Action.Container, * <p> * <i>Note that calling this method is not cheap so avoid calling it * unnecessarily.</i> - * + * * @since 6.7.2 */ public void refreshRowCache() { @@ -2651,7 +2666,7 @@ public class Table extends AbstractSelect implements Action.Container, * Keeps propertyValueConverters if the corresponding id exists in the new * data source and is of a compatible type. * </p> - * + * * @param newDataSource * the new data source. */ @@ -2689,11 +2704,11 @@ public class Table extends AbstractSelect implements Action.Container, * Keeps propertyValueConverters if the corresponding id exists in the new * data source and is of a compatible type. * </p> - * + * * @see Table#setContainerDataSource(Container) * @see Table#setVisibleColumns(Object[]) * @see Table#setConverter(Object, Converter<String, ?>) - * + * * @param newDataSource * the new data source. * @param visibleIds @@ -2768,7 +2783,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if class b can be safely assigned to class a. - * + * * @param a * @param b * @return @@ -2782,7 +2797,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets items ids from a range of key values - * + * * @param startRowKey * The start key * @param endRowKey @@ -2803,7 +2818,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles selection if selection is a multiselection - * + * * @param variables * The variables */ @@ -2882,7 +2897,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Invoked when the value of a variable has changed. - * + * * @see com.vaadin.ui.Select#changeVariables(java.lang.Object, * java.util.Map) */ @@ -3084,7 +3099,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles click event - * + * * @param variables */ private void handleClickEvent(Map<String, Object> variables) { @@ -3138,7 +3153,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Handles the column resize event sent by the client. - * + * * @param variables */ private void handleColumnResizeEvent(Map<String, Object> variables) { @@ -3197,7 +3212,7 @@ public class Table extends AbstractSelect implements Action.Container, * Go to mode where content updates are not done. This is due we want to * bypass expensive content for some reason (like when we know we may have * other content changes on their way). - * + * * @return true if content refresh flag was enabled prior this call */ protected boolean disableContentRefreshing() { @@ -3208,7 +3223,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Go to mode where content content refreshing has effect. - * + * * @param refreshContent * true if content refresh needs to be done */ @@ -3408,7 +3423,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row updates and additions, * which bypass the normal caching mechanism. This is useful for e.g. * TreeTable. - * + * * @return true if this update is a partial row update, false if not. For * plain Table it is always false. */ @@ -3420,7 +3435,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row additions, bypassing the * normal caching mechanism. This is useful for e.g. TreeTable, where * expanding a node should only fetch and add the items inside of that node. - * + * * @return The index of the first added item. For plain Table it is always * 0. */ @@ -3432,7 +3447,7 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable partial row additions, bypassing the * normal caching mechanism. This is useful for e.g. TreeTable, where * expanding a node should only fetch and add the items inside of that node. - * + * * @return the number of rows to be added, starting at the index returned by * {@link #getFirstAddedItemIndex()}. For plain Table it is always * 0. @@ -3445,11 +3460,11 @@ public class Table extends AbstractSelect implements Action.Container, * Subclass and override this to enable removing of rows, bypassing the * normal caching and lazy loading mechanism. This is useful for e.g. * TreeTable, when you need to hide certain rows as a node is collapsed. - * + * * This should return true if the rows pointed to by * {@link #getFirstAddedItemIndex()} and {@link #getAddedRowCount()} should * be hidden instead of added. - * + * * @return whether the rows to add (see {@link #getFirstAddedItemIndex()} * and {@link #getAddedRowCount()}) should be added or hidden. For * plain Table it is always false. @@ -3463,7 +3478,7 @@ public class Table extends AbstractSelect implements Action.Container, * normal caching and lazy loading mechanism. This is useful for updating * the state of certain rows, e.g. in the TreeTable the collapsed state of a * single node is updated using this mechanism. - * + * * @return the index of the first item to be updated. For plain Table it is * always 0. */ @@ -3476,7 +3491,7 @@ public class Table extends AbstractSelect implements Action.Container, * normal caching and lazy loading mechanism. This is useful for updating * the state of certain rows, e.g. in the TreeTable the collapsed state of a * single node is updated using this mechanism. - * + * * @return the number of rows to update, starting at the index returned by * {@link #getFirstUpdatedItemIndex()}. For plain table it is always * 0. @@ -3990,7 +4005,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * A method where extended Table implementations may add their custom * attributes for rows. - * + * * @param target * @param itemId */ @@ -4001,7 +4016,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the cached visible table contents. - * + * * @return the cached visible table contents. */ private Object[][] getVisibleCells() { @@ -4013,11 +4028,11 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the value of property. - * + * * By default if the table is editable the fieldFactory is used to create * editors for table cells. Otherwise formatPropertyValue is used to format * the value representation. - * + * * @param rowId * the Id of the row (same as item Id). * @param colId @@ -4049,7 +4064,7 @@ public class Table extends AbstractSelect implements Action.Container, * default behavior is to bind property straight to Field. If * Property.Viewer type property (e.g. PropertyFormatter) is already set for * field, the property is bound to that Property.Viewer. - * + * * @param rowId * @param colId * @param property @@ -4074,7 +4089,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Formats table cell property values. By default the property.toString() * and return a empty string for null properties. - * + * * @param rowId * the Id of the row (same as item Id). * @param colId @@ -4109,7 +4124,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Registers a new action handler for this container - * + * * @see com.vaadin.event.Action.Container#addActionHandler(Action.Handler) */ @@ -4137,7 +4152,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a previously registered action handler for the contents of this * container. - * + * * @see com.vaadin.event.Action.Container#removeActionHandler(Action.Handler) */ @@ -4176,9 +4191,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies this listener that the Property's value has changed. - * + * * Also listens changes in rendered items to refresh content area. - * + * * @see com.vaadin.data.Property.ValueChangeListener#valueChange(Property.ValueChangeEvent) */ @@ -4209,7 +4224,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies the component that it is connected to an application. - * + * * @see com.vaadin.ui.Component#attach() */ @@ -4222,7 +4237,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Notifies the component that it is detached from the application - * + * * @see com.vaadin.ui.Component#detach() */ @@ -4233,7 +4248,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes all Items from the Container. - * + * * @see com.vaadin.data.Container#removeAllItems() */ @@ -4246,7 +4261,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes the Item identified by <code>ItemId</code> from the Container. - * + * * @see com.vaadin.data.Container#removeItem(Object) */ @@ -4265,7 +4280,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a Property specified by the given Property ID from the Container. - * + * * @see com.vaadin.data.Container#removeContainerProperty(Object) */ @@ -4287,7 +4302,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a new property to the table and show it as a visible column. - * + * * @param propertyId * the Id of the proprty. * @param type @@ -4322,7 +4337,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a new property to the table and show it as a visible column. - * + * * @param propertyId * the Id of the proprty * @param type @@ -4378,7 +4393,7 @@ public class Table extends AbstractSelect implements Action.Container, * Also note that getVisibleColumns() will return the generated columns, * while getContainerPropertyIds() will not. * </p> - * + * * @param id * the id of the column to be added * @param generatedColumn @@ -4407,7 +4422,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the ColumnGenerator used to generate the given column. - * + * * @param columnId * The id of the generated column * @return The ColumnGenerator used for the given columnId or null. @@ -4419,7 +4434,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a generated column previously added with addGeneratedColumn. - * + * * @param columnId * id of the generated column to remove * @return true if the column could be removed (existed in the Table) @@ -4450,7 +4465,7 @@ public class Table extends AbstractSelect implements Action.Container, * architecture. Using {@link #getCurrentPageFirstItemId()} combined with * {@link #getPageLength()} may produce good enough estimates in some * situations. - * + * * @see com.vaadin.ui.Select#getVisibleItemIds() */ @@ -4474,7 +4489,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Container datasource item set change. Table must flush its buffers on * change. - * + * * @see com.vaadin.data.Container.ItemSetChangeListener#containerItemSetChange(com.vaadin.data.Container.ItemSetChangeEvent) */ @@ -4499,7 +4514,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Container datasource property set change. Table must flush its buffers on * change. - * + * * @see com.vaadin.data.Container.PropertySetChangeListener#containerPropertySetChange(com.vaadin.data.Container.PropertySetChangeEvent) */ @@ -4545,7 +4560,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adding new items is not supported. - * + * * @throws UnsupportedOperationException * if set to true. * @see com.vaadin.ui.Select#setNewItemsAllowed(boolean) @@ -4561,7 +4576,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the Item following the Item that corresponds to itemId. - * + * * @see com.vaadin.data.Container.Ordered#nextItemId(java.lang.Object) */ @@ -4573,7 +4588,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the Item preceding the Item that corresponds to the * itemId. - * + * * @see com.vaadin.data.Container.Ordered#prevItemId(java.lang.Object) */ @@ -4584,7 +4599,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the first Item in the Container. - * + * * @see com.vaadin.data.Container.Ordered#firstItemId() */ @@ -4595,7 +4610,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the ID of the last Item in the Container. - * + * * @see com.vaadin.data.Container.Ordered#lastItemId() */ @@ -4607,7 +4622,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Tests if the Item corresponding to the given Item ID is the first Item in * the Container. - * + * * @see com.vaadin.data.Container.Ordered#isFirstId(java.lang.Object) */ @@ -4619,7 +4634,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Tests if the Item corresponding to the given Item ID is the last Item in * the Container. - * + * * @see com.vaadin.data.Container.Ordered#isLastId(java.lang.Object) */ @@ -4630,7 +4645,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds new item after the given item. - * + * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object) */ @@ -4647,7 +4662,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds new item after the given item. - * + * * @see com.vaadin.data.Container.Ordered#addItemAfter(java.lang.Object, * java.lang.Object) */ @@ -4665,10 +4680,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the TableFieldFactory that is used to create editor for table cells. - * + * * The TableFieldFactory is only used if the Table is editable. By default * the DefaultFieldFactory is used. - * + * * @param fieldFactory * the field factory to set. * @see #isEditable @@ -4683,9 +4698,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the TableFieldFactory that is used to create editor for table cells. - * + * * The FieldFactory is only used if the Table is editable. - * + * * @return TableFieldFactory used to create the Field instances. * @see #isEditable */ @@ -4695,18 +4710,18 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is table editable. - * + * * If table is editable a editor of type Field is created for each table * cell. The assigned FieldFactory is used to create the instances. - * + * * To provide custom editors for table cells create a class implementins the * FieldFactory interface, and assign it to table, and set the editable * property to true. - * + * * @return true if table is editable, false oterwise. * @see Field * @see FieldFactory - * + * */ public boolean isEditable() { return editable; @@ -4714,19 +4729,19 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the editable property. - * + * * If table is editable a editor of type Field is created for each table * cell. The assigned FieldFactory is used to create the instances. - * + * * To provide custom editors for table cells create a class implementins the * FieldFactory interface, and assign it to table, and set the editable * property to true. - * + * * @param editable * true if table should be editable by user. * @see Field * @see FieldFactory - * + * */ public void setEditable(boolean editable) { this.editable = editable; @@ -4737,13 +4752,13 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sorts the table. - * + * * @throws UnsupportedOperationException * if the container data source does not implement * Container.Sortable * @see com.vaadin.data.Container.Sortable#sort(java.lang.Object[], * boolean[]) - * + * */ @Override @@ -4775,7 +4790,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sorts the table by currently selected sorting column. - * + * * @throws UnsupportedOperationException * if the container data source does not implement * Container.Sortable @@ -4795,7 +4810,7 @@ public class Table extends AbstractSelect implements Action.Container, * returns. Disabling sorting causes this method to always return an empty * collection. * </p> - * + * * @see com.vaadin.data.Container.Sortable#getSortableContainerPropertyIds() */ @@ -4811,7 +4826,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the currently sorted column property ID. - * + * * @return the Container property id of the currently sorted column. */ public Object getSortContainerPropertyId() { @@ -4820,7 +4835,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the currently sorted column property id. - * + * * @param propertyId * the Container property id of the currently sorted column. */ @@ -4831,7 +4846,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Internal method to set currently sorted column property id. With doSort * flag actual sorting may be bypassed. - * + * * @param propertyId * @param doSort */ @@ -4852,7 +4867,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is the table currently sorted in ascending order. - * + * * @return <code>true</code> if ascending, <code>false</code> if descending. */ public boolean isSortAscending() { @@ -4861,7 +4876,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the table in ascending order. - * + * * @param ascending * <code>true</code> if ascending, <code>false</code> if * descending. @@ -4873,7 +4888,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Internal method to set sort ascending. With doSort flag actual sort can * be bypassed. - * + * * @param ascending * @param doSort */ @@ -4891,10 +4906,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is sorting disabled altogether. - * + * * True iff no sortable columns are given even in the case where data source * would support this. - * + * * @return True iff sorting is disabled. * @deprecated As of 7.0, use {@link #isSortEnabled()} instead */ @@ -4905,7 +4920,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if sorting is enabled. - * + * * @return true if sorting by the user is allowed, false otherwise */ public boolean isSortEnabled() { @@ -4914,7 +4929,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Disables the sorting by the user altogether. - * + * * @param sortDisabled * True iff sorting is disabled. * @deprecated As of 7.0, use {@link #setSortEnabled(boolean)} instead @@ -4930,7 +4945,7 @@ public class Table extends AbstractSelect implements Action.Container, * Setting this to false disallows sorting by the user. It is still possible * to call {@link #sort()}. * </p> - * + * * @param sortEnabled * true to allow the user to sort the table, false to disallow it */ @@ -4945,14 +4960,14 @@ public class Table extends AbstractSelect implements Action.Container, * Used to create "generated columns"; columns that exist only in the Table, * not in the underlying Container. Implement this interface and pass it to * Table.addGeneratedColumn along with an id for the column to be generated. - * + * */ public interface ColumnGenerator extends Serializable { /** * Called by Table when a cell in a generated column needs to be * generated. - * + * * @param source * the source Table * @param itemId @@ -4970,7 +4985,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Set cell style generator for Table. - * + * * @param cellStyleGenerator * New cell style generator or null to remove generator. */ @@ -4984,7 +4999,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the current cell style generator. - * + * */ public CellStyleGenerator getCellStyleGenerator() { return cellStyleGenerator; @@ -5001,7 +5016,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called by Table when a cell (and row) is painted. - * + * * @param source * the source Table * @param itemId @@ -5064,7 +5079,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the drag start mode of the Table. Drag start mode controls how Table * behaves as a drag source. - * + * * @param newDragMode */ public void setDragMode(TableDragMode newDragMode) { @@ -5083,9 +5098,9 @@ public class Table extends AbstractSelect implements Action.Container, /** * Concrete implementation of {@link DataBoundTransferable} for data * transferred from a table. - * + * * @see {@link DataBoundTransferable}. - * + * * @since 6.3 */ public class TableTransferable extends DataBoundTransferable { @@ -5147,7 +5162,7 @@ public class Table extends AbstractSelect implements Action.Container, * Note, that on some clients the mode may not be respected. E.g. on touch * based devices CTRL/SHIFT base selection method is invalid, so touch based * browsers always use the {@link MultiSelectMode#SIMPLE}. - * + * * @param mode * The select mode of the table */ @@ -5158,7 +5173,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the select mode in which multi-select is used. - * + * * @return The multi select mode */ public MultiSelectMode getMultiSelectMode() { @@ -5170,7 +5185,7 @@ public class Table extends AbstractSelect implements Action.Container, * from server once per drag and drop operation. Developer must override one * method that decides on which rows the currently dragged data can be * dropped. - * + * * <p> * Initially pretty much no data is sent to client. On first required * criterion check (per drag request) the client side data structure is @@ -5287,7 +5302,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the property id of the column which header was pressed - * + * * @return The column propety id */ public Object getPropertyId() { @@ -5321,7 +5336,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the component * @param propertyId @@ -5337,7 +5352,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the property id of the column which header was pressed - * + * * @return The column propety id */ public Object getPropertyId() { @@ -5353,7 +5368,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called when a user clicks a header column cell - * + * * @param event * The event which contains information about the column and * the mouse click event @@ -5369,7 +5384,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Called when a user clicks a footer column cell - * + * * @param event * The event which contains information about the column and * the mouse click event @@ -5384,7 +5399,7 @@ public class Table extends AbstractSelect implements Action.Container, * The listener will receive events which contain information about which * column was clicked and some details about the mouse event. * </p> - * + * * @param listener * The handler which should handle the header click events. */ @@ -5405,7 +5420,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a header click listener - * + * * @param listener * The listener to remove. */ @@ -5430,7 +5445,7 @@ public class Table extends AbstractSelect implements Action.Container, * The listener will receive events which contain information about which * column was clicked and some details about the mouse event. * </p> - * + * * @param listener * The handler which should handle the footer click events. */ @@ -5451,7 +5466,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a footer click listener - * + * * @param listener * The listener to remove. */ @@ -5471,7 +5486,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Gets the footer caption beneath the rows - * + * * @param propertyId * The propertyId of the column * * @return The caption of the footer or NULL if not set @@ -5483,10 +5498,10 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the column footer caption. The column footer caption is the text * displayed beneath the column if footers have been set visible. - * + * * @param propertyId * The properyId of the column - * + * * @param footer * The caption of the footer */ @@ -5506,7 +5521,7 @@ public class Table extends AbstractSelect implements Action.Container, * The footer can be used to add column related data like sums to the bottom * of the Table using setColumnFooter(Object propertyId, String footer). * </p> - * + * * @param visible * Should the footer be visible */ @@ -5519,7 +5534,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Is the footer currently visible? - * + * * @return Returns true if visible else false */ public boolean isFooterVisible() { @@ -5551,7 +5566,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the event * @param propertyId @@ -5571,7 +5586,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the column property id of the column that was resized. - * + * * @return The column property id */ public Object getPropertyId() { @@ -5580,7 +5595,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the width in pixels of the column before the resize event - * + * * @return Width in pixels */ public int getPreviousWidth() { @@ -5589,7 +5604,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Get the width in pixels of the column after the resize event - * + * * @return Width in pixels */ public int getCurrentWidth() { @@ -5604,7 +5619,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method is triggered when the column has been resized - * + * * @param event * The event which contains the column property id, the * previous width of the column and the current width of the @@ -5616,7 +5631,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a column resize listener to the Table. A column resize listener is * called when a user resizes a columns width. - * + * * @param listener * The listener to attach to the Table */ @@ -5637,7 +5652,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a column resize listener from the Table. - * + * * @param listener * The listener to remove */ @@ -5674,7 +5689,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Constructor - * + * * @param source * The source of the event */ @@ -5691,7 +5706,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * This method is triggered when the column has been reordered - * + * * @param event */ public void columnReorder(ColumnReorderEvent event); @@ -5700,7 +5715,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Adds a column reorder listener to the Table. A column reorder listener is * called when a user reorders columns. - * + * * @param listener * The listener to attach to the Table */ @@ -5720,7 +5735,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Removes a column reorder listener from the Table. - * + * * @param listener * The listener to remove */ @@ -5741,7 +5756,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Set the item description generator which generates tooltips for cells and * rows in the Table - * + * * @param generator * The generator to use or null to disable */ @@ -5766,7 +5781,7 @@ public class Table extends AbstractSelect implements Action.Container, * Row generators can be used to replace certain items in a table with a * generated string. The generator is called each time the table is * rendered, which means that new strings can be generated each time. - * + * * Row generators can be used for e.g. summary rows or grouping of items. */ public interface RowGenerator extends Serializable { @@ -5792,7 +5807,7 @@ public class Table extends AbstractSelect implements Action.Container, * For custom styling of a generated row you can combine a RowGenerator * with a CellStyleGenerator. * <p> - * + * * @param table * The Table that is being painted * @param itemId @@ -5811,7 +5826,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Creates a new generated row. If only one string is passed in, columns * are automatically spanned. - * + * * @param text */ public GeneratedRow(String... text) { @@ -5846,7 +5861,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * If set to true, all strings passed to {@link #setText(String...)} * will be rendered as HTML. - * + * * @param htmlContentAllowed */ public void setHtmlContentAllowed(boolean htmlContentAllowed) { @@ -5860,7 +5875,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * If set to true, only one string will be rendered, spanning the entire * row. - * + * * @param spanColumns */ public void setSpanColumns(boolean spanColumns) { @@ -5871,7 +5886,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Assigns a row generator to the table. The row generator will be able to * replace rows in the table when it is rendered. - * + * * @param generator * the new row generator */ @@ -5893,7 +5908,7 @@ public class Table extends AbstractSelect implements Action.Container, * The converter is used to format the the data for the given property id * before displaying it in the table. * </p> - * + * * @param propertyId * The propertyId to format using the converter * @param converter @@ -5918,7 +5933,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Checks if there is a converter set explicitly for the given property id. - * + * * @param propertyId * The propertyId to check * @return true if a converter has been set for the property id, false @@ -5930,7 +5945,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Returns the converter used to format the given propertyId. - * + * * @param propertyId * The propertyId to check * @return The converter used to format the propertyId or null if no diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index a72cbe5c30..5abeea9480 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -549,8 +549,6 @@ public abstract class UI extends AbstractSingleComponentContainer implements private boolean resizeLazy = false; - private String theme; - private Navigator navigator; private PushConnection pushConnection = null; @@ -633,7 +631,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements this.embedId = embedId; // Actual theme - used for finding CustomLayout templates - theme = request.getParameter("theme"); + getState().theme = request.getParameter("theme"); getPage().init(request); @@ -1135,12 +1133,31 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** - * Gets the theme that was used when the UI was initialized. + * Gets the theme currently in use by this UI * * @return the theme name */ public String getTheme() { - return theme; + return getState(false).theme; + } + + /** + * Sets the theme currently in use by this UI + * <p> + * Calling this method will remove the old theme (CSS file) from the + * application and add the new theme. + * <p> + * Note that this method is NOT SAFE to call in a portal environment or + * other environment where there are multiple UIs on the same page. The old + * CSS file will be removed even if there are other UIs on the page which + * are still using it. + * + * @since 7.3 + * @param theme + * The new theme name + */ + public void setTheme(String theme) { + getState().theme = theme; } /** diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java index 869c32751a..4c248d68ae 100644 --- a/server/src/com/vaadin/ui/Upload.java +++ b/server/src/com/vaadin/ui/Upload.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -35,16 +35,16 @@ import com.vaadin.util.ReflectTools; /** * Component for uploading files from client to server. - * + * * <p> * The visible component consists of a file name input box and a browse button * and an upload submit button to start uploading. - * + * * <p> * The Upload component needs a java.io.OutputStream to write the uploaded data. * You need to implement the Upload.Receiver interface and return the output * stream in the receiveUpload() method. - * + * * <p> * You can get an event regarding starting (StartedEvent), progress * (ProgressEvent), and finishing (FinishedEvent) of upload by implementing @@ -52,22 +52,22 @@ import com.vaadin.util.ReflectTools; * FinishedListener is called for both failed and succeeded uploads. If you wish * to separate between these two cases, you can use SucceededListener * (SucceededEvenet) and FailedListener (FailedEvent). - * + * * <p> * The upload component does not itself show upload progress, but you can use * the ProgressIndicator for providing progress feedback by implementing * ProgressListener and updating the indicator in updateProgress(). - * + * * <p> * Setting upload component immediate initiates the upload as soon as a file is * selected, instead of the common pattern of file selection field and upload * button. - * + * * <p> * Note! Because of browser dependent implementations of <input type="file"> * element, setting size for Upload component is not supported. For some * browsers setting size may work to some extend. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -112,7 +112,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Creates a new instance of Upload. - * + * * The receiver must be set before performing an upload. */ public Upload() { @@ -132,7 +132,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Invoked when the value of a variable has changed. - * + * * @see com.vaadin.ui.AbstractComponent#changeVariables(java.lang.Object, * java.util.Map) */ @@ -150,7 +150,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Paints the content of this component. - * + * * @param target * Target to paint the content on. * @throws PaintException @@ -189,7 +189,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Interface that must be implemented by the upload receivers to provide the * Upload component an output stream to write the uploaded data. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -197,7 +197,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Invoked when a new upload arrives. - * + * * @param filename * the desired filename of the upload, usually as specified * by the client. @@ -242,7 +242,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, * of whether the reception was successful or failed. If you wish to * distinguish between the two cases, use either SucceededEvent or * FailedEvent, which are both subclasses of the FinishedEvent. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -264,7 +264,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, private final String filename; /** - * + * * @param source * the source of the file. * @param filename @@ -284,7 +284,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Uploads where the event occurred. - * + * * @return the Source of the event. */ public Upload getUpload() { @@ -293,7 +293,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the file name. - * + * * @return the filename. */ public String getFilename() { @@ -302,7 +302,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the MIME Type of the file. - * + * * @return the MIME type. */ public String getMIMEType() { @@ -311,7 +311,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the length of the file. - * + * * @return the length. */ public long getLength() { @@ -323,7 +323,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload.FailedEvent event is sent when the upload is received, but the * reception is interrupted for some reason. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -332,7 +332,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, private Exception reason = null; /** - * + * * @param source * @param filename * @param MIMEType @@ -346,7 +346,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** - * + * * @param source * @param filename * @param MIMEType @@ -360,7 +360,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the exception that caused the failure. - * + * * @return the exception that caused the failure, null if n/a */ public Exception getReason() { @@ -375,7 +375,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, public static class NoOutputStreamEvent extends FailedEvent { /** - * + * * @param source * @param filename * @param MIMEType @@ -393,7 +393,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, public static class NoInputStreamEvent extends FailedEvent { /** - * + * * @param source * @param filename * @param MIMEType @@ -409,14 +409,14 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload.SucceededEvent event is sent when the upload is received * successfully. - * + * * @author Vaadin Ltd. * @since 3.0 */ public static class SucceededEvent extends FinishedEvent { /** - * + * * @param source * @param filename * @param MIMEType @@ -431,7 +431,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload.StartedEvent event is sent when the upload is started to received. - * + * * @author Vaadin Ltd. * @since 5.0 */ @@ -445,7 +445,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, private final long length; /** - * + * * @param source * @param filename * @param MIMEType @@ -461,7 +461,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Uploads where the event occurred. - * + * * @return the Source of the event. */ public Upload getUpload() { @@ -470,7 +470,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the file name. - * + * * @return the filename. */ public String getFilename() { @@ -479,7 +479,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the MIME Type of the file. - * + * * @return the MIME type. */ public String getMIMEType() { @@ -498,7 +498,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload.ChangeEvent event is sent when the value (filename) of the upload * changes. - * + * * @since 7.2 */ public static class ChangeEvent extends Component.Event { @@ -512,7 +512,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Uploads where the event occurred. - * + * * @return the Source of the event. */ @Override @@ -522,7 +522,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the file name. - * + * * @return the filename. */ public String getFilename() { @@ -533,7 +533,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Receives the events when the upload starts. - * + * * @author Vaadin Ltd. * @since 5.0 */ @@ -541,7 +541,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload has started. - * + * * @param event * the Upload started event. */ @@ -550,7 +550,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Receives the events when the uploads are ready. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -558,7 +558,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload has finished. - * + * * @param event * the Upload finished event. */ @@ -567,7 +567,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Receives events when the uploads are finished, but unsuccessful. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -575,7 +575,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload has finished unsuccessfully. - * + * * @param event * the Upload failed event. */ @@ -584,7 +584,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Receives events when the uploads are successfully finished. - * + * * @author Vaadin Ltd. * @since 3.0 */ @@ -592,7 +592,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Upload successfull.. - * + * * @param event * the Upload successfull event. */ @@ -601,7 +601,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Listener for {@link ChangeEvent} - * + * * @since 7.2 */ public interface ChangeListener extends Serializable { @@ -611,7 +611,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * A file has been selected but upload has not yet started. - * + * * @param event * the change event */ @@ -620,7 +620,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Adds the upload started event listener. - * + * * @param listener * the Listener to be added. */ @@ -639,7 +639,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Removes the upload started event listener. - * + * * @param listener * the Listener to be removed. */ @@ -658,7 +658,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Adds the upload received event listener. - * + * * @param listener * the Listener to be added. */ @@ -677,7 +677,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Removes the upload received event listener. - * + * * @param listener * the Listener to be removed. */ @@ -696,7 +696,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Adds the upload interrupted event listener. - * + * * @param listener * the Listener to be added. */ @@ -715,7 +715,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Removes the upload interrupted event listener. - * + * * @param listener * the Listener to be removed. */ @@ -734,7 +734,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Adds the upload success event listener. - * + * * @param listener * the Listener to be added. */ @@ -753,7 +753,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Removes the upload success event listener. - * + * * @param listener * the Listener to be removed. */ @@ -771,10 +771,10 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** - * Adds the upload success event listener. - * + * Adds the upload progress event listener. + * * @param listener - * the Listener to be added. + * the progress listener to be added */ public void addProgressListener(ProgressListener listener) { if (progressListeners == null) { @@ -793,10 +793,10 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** - * Removes the upload success event listener. - * + * Removes the upload progress event listener. + * * @param listener - * the Listener to be removed. + * the progress listener to be removed */ public void removeProgressListener(ProgressListener listener) { if (progressListeners != null) { @@ -806,7 +806,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Adds a filename change event listener - * + * * @param listener * the Listener to add */ @@ -817,7 +817,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Removes a filename change event listener - * + * * @param listener * the listener to be removed */ @@ -836,7 +836,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Emit upload received event. - * + * * @param filename * @param MIMEType * @param length @@ -848,7 +848,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Emits the upload failed event. - * + * * @param filename * @param MIMEType * @param length @@ -877,11 +877,11 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Emits the upload success event. - * + * * @param filename * @param MIMEType * @param length - * + * */ protected void fireUploadSuccess(String filename, String MIMEType, long length) { @@ -890,12 +890,12 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Emits the progress event. - * + * * @param totalBytes * bytes received so far * @param contentLength * actual size of the file being uploaded, if known - * + * */ protected void fireUpdateProgress(long totalBytes, long contentLength) { // this is implemented differently than other listeners to maintain @@ -911,7 +911,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Returns the current receiver. - * + * * @return the StreamVariable. */ public Receiver getReceiver() { @@ -920,7 +920,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Sets the receiver. - * + * * @param receiver * the receiver to set. */ @@ -938,7 +938,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets the Tabulator index of this Focusable component. - * + * * @see com.vaadin.ui.Component.Focusable#getTabIndex() */ @Override @@ -948,7 +948,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Sets the Tabulator index of this Focusable component. - * + * * @see com.vaadin.ui.Component.Focusable#setTabIndex(int) */ @Override @@ -959,7 +959,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Go into upload state. This is to prevent double uploading on same * component. - * + * * Warning: this is an internal method used by the framework and should not * be used by user of the Upload component. Using it results in the Upload * component going in wrong state and not working. It is currently public @@ -986,7 +986,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Go into state where new uploading can begin. - * + * * Warning: this is an internal method used by the framework and should not * be used by user of the Upload component. */ @@ -1003,7 +1003,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Gets read bytes of the file currently being uploaded. - * + * * @return bytes */ public long getBytesRead() { @@ -1013,7 +1013,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, /** * Returns size of file currently being uploaded. Value sane only during * upload. - * + * * @return size in bytes */ public long getUploadSize() { @@ -1026,7 +1026,7 @@ public class Upload extends AbstractComponent implements Component.Focusable, public interface ProgressListener extends Serializable { /** * Updates progress to listener - * + * * @param readBytes * bytes transferred * @param contentLength @@ -1055,12 +1055,12 @@ public class Upload extends AbstractComponent implements Component.Focusable, * {@link #setImmediate(boolean)}, the file choose (html input with type * "file") is hidden and only the button with this text is shown. * <p> - * + * * <p> * <strong>Note</strong> the string given is set as is to the button. HTML * formatting is not stripped. Be sure to properly validate your value * according to your needs. - * + * * @param buttonCaption * text for upload components button. */ diff --git a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java index 7c19395df2..a8804caedb 100644 --- a/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java +++ b/server/src/com/vaadin/ui/components/calendar/ContainerEventProvider.java @@ -262,6 +262,7 @@ public class ContainerEventProvider implements CalendarEditableEventProvider, private int[] getFirstAndLastEventIndex(Date start, Date end) { int startIndex = 0; int size = container.size(); + assert size >= 0; int endIndex = size - 1; if (start != null) { diff --git a/server/src/com/vaadin/ui/themes/ValoTheme.java b/server/src/com/vaadin/ui/themes/ValoTheme.java index 63fa13dce4..ad949c6a32 100644 --- a/server/src/com/vaadin/ui/themes/ValoTheme.java +++ b/server/src/com/vaadin/ui/themes/ValoTheme.java @@ -15,6 +15,7 @@ */ package com.vaadin.ui.themes; +import com.vaadin.server.FontAwesome; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.Table.ColumnHeaderMode; @@ -185,6 +186,18 @@ public class ValoTheme { */ public static final String LABEL_FAILURE = "failure"; + /** + * Spinner style. Add this style name to an empty Label to create a spinner. + * + * <h4>Example</h4> + * + * <pre> + * Label spinner = new Label(); + * spinner.addStyleName(ValoTheme.LABEL_SPINNER); + * </pre> + */ + public static final String LABEL_SPINNER = "spinner"; + /*************************************************************************** * * Button styles @@ -457,6 +470,12 @@ public class ValoTheme { */ public static final String OPTIONGROUP_LARGE = "large"; + /** + * Display the options horizontally in a row (by default the items are + * stacked vertically). + */ + public static final String OPTIONGROUP_HORIZONTAL = "horizontal"; + /*************************************************************************** * * Slider styles @@ -738,7 +757,7 @@ public class ValoTheme { /** * Removes the borders and background from any direct child field components * (TextField, TextArea, DateField, ComboBox) in the layout. Reduces the - * spacing between the form rows adds separator lines between them. + * spacing between the form rows and adds separator lines between them. */ public static final String FORMLAYOUT_LIGHT = "light"; @@ -762,6 +781,31 @@ public class ValoTheme { */ public static final String LAYOUT_WELL = "well"; + /** + * Make a HorizontalLayout wrap contained components to a new line when the + * isn't enough space. + */ + public static final String LAYOUT_HORIZONTAL_WRAPPING = "wrapping"; + + /** + * Add this style name to a CssLayout to create a grouped set of components, + * i.e. a row of components which are joined seamlessly together. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout group = new CssLayout(); + * group.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP); + * + * TextField field = new TextField(); + * group.addComponent(field); + * + * Button button = new Button("Action"); + * group.addComponent(button); + * </pre> + */ + public static final String LAYOUT_COMPONENT_GROUP = "v-component-group"; + /*************************************************************************** * * Valo menu styles @@ -769,8 +813,25 @@ public class ValoTheme { **************************************************************************/ /** - * Set the primary style name of a CssLayout to this, and add any number of - * layouts with the {@link #MENU_PART} style inside it. + * <p> + * Set the <em><b>primary</b></em> style name of a CssLayout to this, and + * add any number of layouts with the {@link #MENU_PART} style inside it. + * </p> + * + * <p> + * The menu style is used to create a sidebar navigation menu for the + * application, usually action as the main navigation for the different + * sections of the application. It usually consists of at least a number of + * {@link #MENU_ITEM}s, and possibly some {@link #MENU_SUBTITLE}s and a + * {@link #MENU_TITLE}. + * </p> + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menuArea = new CssLayout(); + * menuArea.setPrimaryStyleName(ValoTheme.MENU_ROOT); + * </pre> */ public static final String MENU_ROOT = "valo-menu"; @@ -778,31 +839,124 @@ public class ValoTheme { * Add this style name to any layout and place it inside a layout with the * {@link #MENU_ROOT} style to build a menu component. Use the additional * MENU styles for individual components inside the layout. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menu = new CssLayout(); + * menu.addStyleName(ValoTheme.MENU_PART); + * </pre> */ public static final String MENU_PART = "valo-menu-part"; /** - * TODO + * Add this style name to any layout with the {@link #MENU_PART} style name + * to make any menu items inside the menu emphasize the icons more than the + * captions. Useful on narrower viewport widths, since the menu width is + * decreased quite dramatically, making more space for the content of the + * application. + * + * <h4>Example</h4> + * + * <pre> + * CssLayout menu = new CssLayout(); + * menu.addStyleName(ValoTheme.MENU_PART); + * menu.addStyleName(ValoTheme.MENU_PART_LARGE_ICONS); + * </pre> + */ + public static final String MENU_PART_LARGE_ICONS = "large-icons"; + + /** + * <p> + * Add this style name to any layout to make a header area for a menu + * (intended to be placed in side a {@link #MENU_PART} layout). You can add + * any components inside it, but usually you would place a Label inside. + * </p> + * + * <p> + * Any MenuBar component that you place inside this layout will match the + * style of the title, allowing an easy way to add a toolbar to the title + * layout. + * </p> */ public static final String MENU_TITLE = "valo-menu-title"; /** - * TODO + * Set the <em><b>primary</b></em> style name of a Label or a Button to this + * style name to create a section divider in a menu. */ public static final String MENU_SUBTITLE = "valo-menu-subtitle"; /** - * TODO + * <p> + * Set the <em><b>primary</b></em> style name of a Button to this style name + * to create a clickable menu item in the menu. + * </p> + * + * <h4>Selected item</h4> + * <p> + * Add an additional style name <b><code>selected</code></b> to it to make + * it the selected item in the menu. + * </p> + * + * <h4>Example</h4> + * + * <pre> + * Button item = new Button(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.addStyleName("selected"); + * </pre> */ - public static final String MENU_ITEM = "valo-menu-title"; + public static final String MENU_ITEM = "valo-menu-item"; /** - * TODO + * Add a SPAN element with this style name inside a {@link #MENU_SUBTITLE} + * or {@link #MENU_ITEM} to add an additional badge indicator to the + * subtitle/item. The Label/Button needs to allow HTML content in order to + * use this style name. + * + * <h4>Examples</h4> + * + * <pre> + * Button item = new Button(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.setHtmlContentAllowed(true); + * item.setCaption("Item Caption <span class=\"" + ValoTheme.MENU_BADGE + * + "\">Badge text</span>"); + * </pre> + * + * <pre> + * Label item = new Label(); + * item.setPrimaryStyleName(ValoTheme.MENU_ITEM); + * item.setContentMode(ContentMode.HTML); + * item.setCaption("Item Caption <span class=\"" + ValoTheme.MENU_BADGE + * + "\">Badge text</span>"); + * </pre> */ public static final String MENU_BADGE = "valo-menu-badge"; /** - * TODO + * <p> + * Set the <em><b>primary</b></em> style name of a Label or a Button to this + * style name to create an application logo. The logo is designed to be + * placed inside a {@link #MENU_PART} layout. + * </p> + * + * <p> + * The text content of the logo should be very short, since the logo area + * only shows approximately three letters. Using one of the + * {@link FontAwesome} icons is a good way to quickly create a logo for your + * application. + * </p> + * </p> + * + * <h4>Example</h4> + * + * <pre> + * Label logo = new Label(FontAwesome.ROCKET.getHtml(), ContentMode.HTML); + * logo.setSizeUndefined(); + * logo.setPrimaryStyleName(ValoTheme.MENU_LOGO); + * </pre> */ public static final String MENU_LOGO = "valo-menu-logo"; diff --git a/server/src/com/vaadin/util/CurrentInstance.java b/server/src/com/vaadin/util/CurrentInstance.java index 00d2e7346d..d11fa175ac 100644 --- a/server/src/com/vaadin/util/CurrentInstance.java +++ b/server/src/com/vaadin/util/CurrentInstance.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -52,12 +52,14 @@ import com.vaadin.ui.UI; * <p> * Non-inheritable: {@link VaadinRequest}, {@link VaadinResponse}. * </p> - * + * * @author Vaadin Ltd * @since 7.0.0 */ public class CurrentInstance implements Serializable { private static final Object NULL_OBJECT = new Object(); + private static final CurrentInstance CURRENT_INSTANCE_NULL = new CurrentInstance( + NULL_OBJECT, true); private final WeakReference<Object> instance; private final boolean inheritable; @@ -90,7 +92,7 @@ public class CurrentInstance implements Serializable { /** * Gets the current instance of a specific type if available. - * + * * @param type * the class to get an instance of * @return the current instance or the provided type, or <code>null</code> @@ -148,10 +150,10 @@ public class CurrentInstance implements Serializable { /** * Sets the current instance of the given type. - * + * * @see #setInheritable(Class, Object) * @see ThreadLocal - * + * * @param type * the class that should be used when getting the current * instance back @@ -167,10 +169,10 @@ public class CurrentInstance implements Serializable { * instance that is inheritable will be available for child threads and in * code run by {@link VaadinSession#access(Runnable)} and * {@link UI#access(Runnable)}. - * + * * @see #set(Class, Object) * @see InheritableThreadLocal - * + * * @param type * the class that should be used when getting the current * instance back @@ -181,17 +183,18 @@ public class CurrentInstance implements Serializable { set(type, instance, true); } - private static <T> void set(Class<T> type, T instance, boolean inheritable) { + private static <T> CurrentInstance set(Class<T> type, T instance, + boolean inheritable) { Map<Class<?>, CurrentInstance> map = instances.get(); + CurrentInstance previousInstance = null; if (instance == null) { // remove the instance - if (map == null) { - return; - } - map.remove(type); - if (map.isEmpty()) { - instances.remove(); - map = null; + if (map != null) { + previousInstance = map.remove(type); + if (map.isEmpty()) { + instances.remove(); + map = null; + } } } else { assert type.isInstance(instance) : "Invald instance type"; @@ -200,8 +203,8 @@ public class CurrentInstance implements Serializable { instances.set(map); } - CurrentInstance previousInstance = map.put(type, - new CurrentInstance(instance, inheritable)); + previousInstance = map.put(type, new CurrentInstance(instance, + inheritable)); if (previousInstance != null) { assert previousInstance.inheritable == inheritable : "Inheritable status mismatch for " + type @@ -211,6 +214,10 @@ public class CurrentInstance implements Serializable { + inheritable + ")"; } } + if (previousInstance == null) { + previousInstance = CURRENT_INSTANCE_NULL; + } + return previousInstance; } /** @@ -223,9 +230,9 @@ public class CurrentInstance implements Serializable { /** * Restores the given instances to the given values. Note that this should * only be used internally to restore Vaadin classes. - * + * * @since 7.1 - * + * * @param old * A Class -> CurrentInstance map to set as current instances */ @@ -267,9 +274,9 @@ public class CurrentInstance implements Serializable { /** * Gets the currently set instances so that they can later be restored using * {@link #restoreInstances(Map)}. - * + * * @since 7.1 - * + * * @param onlyInheritable * <code>true</code> if only the inheritable instances should be * included; <code>false</code> to get all instances. @@ -305,20 +312,17 @@ public class CurrentInstance implements Serializable { * Sets current instances for the UI and all related classes. The previously * defined values can be restored by passing the returned map to * {@link #restoreInstances(Map)}. - * + * * @since 7.1 - * + * * @param ui * The UI * @return A map containing the old values of the instances that this method * updated. */ public static Map<Class<?>, CurrentInstance> setCurrent(UI ui) { - Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>(); - old.put(UI.class, - new CurrentInstance(getSameOrNullObject(UI.getCurrent()), true)); - UI.setCurrent(ui); - old.putAll(setCurrent(ui.getSession())); + Map<Class<?>, CurrentInstance> old = setCurrent(ui.getSession()); + old.put(UI.class, set(UI.class, ui, true)); return old; } @@ -326,9 +330,9 @@ public class CurrentInstance implements Serializable { * Sets current instances for the {@link VaadinSession} and all related * classes. The previously defined values can be restored by passing the * returned map to {@link #restoreInstances(Map)}. - * + * * @since 7.1 - * + * * @param session * The VaadinSession * @return A map containing the old values of the instances this method @@ -337,33 +341,15 @@ public class CurrentInstance implements Serializable { public static Map<Class<?>, CurrentInstance> setCurrent( VaadinSession session) { Map<Class<?>, CurrentInstance> old = new HashMap<Class<?>, CurrentInstance>(); - old.put(VaadinSession.class, new CurrentInstance( - getSameOrNullObject(VaadinSession.getCurrent()), true)); - old.put(VaadinService.class, new CurrentInstance( - getSameOrNullObject(VaadinService.getCurrent()), true)); + old.put(VaadinSession.class, set(VaadinSession.class, session, true)); VaadinService service = null; if (session != null) { service = session.getService(); } - - VaadinSession.setCurrent(session); - VaadinService.setCurrent(service); - + old.put(VaadinService.class, set(VaadinService.class, service, true)); return old; } - /** - * Returns {@code object} unless it is null, in which case #NULL_OBJECT is - * returned. - * - * @param object - * The instance to return if non-null. - * @return {@code object} or #NULL_OBJECT if {@code object} is null. - */ - private static Object getSameOrNullObject(Object object) { - return object == null ? NULL_OBJECT : object; - } - private static Logger getLogger() { return Logger.getLogger(CurrentInstance.class.getName()); } diff --git a/server/tests/src/com/vaadin/data/util/ContainerSizeAssertTest.java b/server/tests/src/com/vaadin/data/util/ContainerSizeAssertTest.java new file mode 100644 index 0000000000..04fd8d3cd1 --- /dev/null +++ b/server/tests/src/com/vaadin/data/util/ContainerSizeAssertTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.data.util; + +import org.junit.Test; + +import com.vaadin.data.Container; +import com.vaadin.ui.Table; + +public class ContainerSizeAssertTest { + + @Test(expected = AssertionError.class) + public void testNegativeSizeAssert() { + Table table = createAttachedTable(); + + table.setContainerDataSource(createNegativeSizeContainer()); + } + + @Test + public void testZeroSizeNoAssert() { + Table table = createAttachedTable(); + + table.setContainerDataSource(new IndexedContainer()); + } + + private Container createNegativeSizeContainer() { + return new IndexedContainer() { + @Override + public int size() { + return -1; + } + }; + } + + private Table createAttachedTable() { + return new Table() { + private boolean initialized = true; + + @Override + public boolean isAttached() { + // This returns false until the super constructor has finished + return initialized; + } + }; + } +} diff --git a/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java index 6e40c57718..bf2b809529 100644 --- a/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java +++ b/server/tests/src/com/vaadin/server/VaadinPortletRequestTests.java @@ -42,7 +42,8 @@ public class VaadinPortletRequestTests { @Test public void defaultValueForPortletPreferenceIsNull() { - when(preferences.getValue(anyString(), isNull(String.class))).thenReturn(null); + when(preferences.getValue(anyString(), isNull(String.class))) + .thenReturn(null); String value = sut.getPortletPreference("foo"); diff --git a/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java new file mode 100644 index 0000000000..30f1c85fef --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/CsrfTokenMissingTestServer.java @@ -0,0 +1,248 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.server; + +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; + +import org.easymock.EasyMock; +import org.json.JSONException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.server.ServiceException; +import com.vaadin.server.VaadinService; +import com.vaadin.server.VaadinServlet; +import com.vaadin.server.VaadinServletRequest; +import com.vaadin.server.VaadinServletService; +import com.vaadin.server.VaadinSession; +import com.vaadin.server.communication.ServerRpcHandler.RpcRequest; +import com.vaadin.shared.ApplicationConstants; +import com.vaadin.tests.util.AlwaysLockedVaadinSession; +import com.vaadin.tests.util.MockDeploymentConfiguration; + +/** + * Test the actual csrf token validation by the server. + * + * @since + * @author Vaadin Ltd + */ +public class CsrfTokenMissingTestServer { + + // Dummy fields just to run the test. + private VaadinServlet mockServlet; + + // The mock deployment configuration. + private MockDeploymentConfiguration mockDeploymentConfiguration; + + private VaadinServletService mockService; + + // The mock UI session. + private VaadinSession mockSession; + + // The mock vaadin request. + private VaadinServletRequest vaadinRequest; + + /** + * Initialize the mock servlet and other stuff for our tests. + */ + @Before + public void initMockStuff() throws ServiceException { + mockServlet = new VaadinServlet(); + mockDeploymentConfiguration = new MockDeploymentConfiguration(); + + mockService = new VaadinServletService(mockServlet, + mockDeploymentConfiguration); + + mockSession = new AlwaysLockedVaadinSession(mockService); + + vaadinRequest = new VaadinServletRequest( + EasyMock.createMock(HttpServletRequest.class), mockService); + + } + + private enum TokenType { + MISSING, INVALID, VALID + } + + private TokenType tokenType; + + private String invalidToken; + + public String getInvalidToken() { + if (invalidToken == null) { + // Just making sure this will never be in the same format as a valid + // token. + invalidToken = UUID.randomUUID().toString().substring(1); + } + return invalidToken; + } + + private String getValidToken() { + return mockSession.getCsrfToken(); + } + + /* + * Gets the payload with the default token. + */ + private String getPayload() { + switch (tokenType) { + case MISSING: + return getPayload(null); + + case INVALID: + return getPayload(getInvalidToken()); + + case VALID: + return getPayload(getValidToken()); + } + + return null; + } + + /* + * Gets the payload with the specified token. + */ + private String getPayload(String token) { + return "{" + + (token != null ? "\"csrfToken\":" + "\"" + token + "\", " + : "") + + "\"rpc\":[[\"0\",\"com.vaadin.shared.ui.ui.UIServerRpc\",\"resize\",[\"449\",\"1155\",\"1155\",\"449\"]],[\"4\",\"com.vaadin.shared.ui.button.ButtonServerRpc\",\"click\",[{\"clientY\":\"53\", \"clientX\":\"79\", \"shiftKey\":false, \"button\":\"LEFT\", \"ctrlKey\":false, \"type\":\"1\", \"metaKey\":false, \"altKey\":false, \"relativeY\":\"17\", \"relativeX\":\"61\"}]]], \"syncId\":1}"; + } + + /* + * Init the test parameters. + */ + private void initTest(boolean enableSecurity, TokenType tokenType) { + mockDeploymentConfiguration.setXsrfProtectionEnabled(enableSecurity); + this.tokenType = tokenType; + } + + /* + * Create the requets. + */ + private RpcRequest createRequest() { + try { + return new RpcRequest(getPayload(), vaadinRequest); + } catch (JSONException e) { + LOGGER.log(Level.SEVERE, "", e); + + Assert.assertTrue(false); + return null; + } + } + + /* + * Gets whether the token from the request is the default one. + */ + private boolean isDefaultToken(RpcRequest rpcRequest) { + return ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE.equals(rpcRequest + .getCsrfToken()); + } + + /* + * Gets whether the token from the request is the invalid one. + */ + private boolean isInvalidToken(RpcRequest rpcRequest) { + return getInvalidToken().equals(rpcRequest.getCsrfToken()); + } + + /* + * Gets whether the token from the request is the valid one. + */ + private boolean isValidToken(RpcRequest rpcRequest) { + return getValidToken().equals(rpcRequest.getCsrfToken()); + } + + /* + * Gets whether the token from the request is valid. + */ + private boolean isRequestValid(RpcRequest rpcRequest) { + return VaadinService.isCsrfTokenValid(mockSession, + rpcRequest.getCsrfToken()); + } + + private static Logger LOGGER = Logger + .getLogger(CsrfTokenMissingTestServer.class.getName()); + static { + LOGGER.setLevel(Level.ALL); + } + + @Test + public void securityOnAndNoToken() { + initTest(true, TokenType.MISSING); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isDefaultToken(rpcRequest)); + Assert.assertFalse(isRequestValid(rpcRequest)); + } + + @Test + public void securityOffAndNoToken() { + initTest(false, TokenType.MISSING); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isDefaultToken(rpcRequest)); + Assert.assertTrue(isRequestValid(rpcRequest)); + } + + @Test + public void securityOnAndInvalidToken() { + initTest(true, TokenType.INVALID); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isInvalidToken(rpcRequest)); + Assert.assertFalse(isRequestValid(rpcRequest)); + } + + @Test + public void securityOffAndInvalidToken() { + initTest(false, TokenType.INVALID); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isInvalidToken(rpcRequest)); + Assert.assertTrue(isRequestValid(rpcRequest)); + } + + @Test + public void securityOnAndValidToken() { + initTest(true, TokenType.VALID); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isValidToken(rpcRequest)); + Assert.assertTrue(isRequestValid(rpcRequest)); + } + + @Test + public void securityOffAndValidToken() { + initTest(false, TokenType.VALID); + + RpcRequest rpcRequest = createRequest(); + + Assert.assertTrue(isValidToken(rpcRequest)); + Assert.assertTrue(isRequestValid(rpcRequest)); + } + +} diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java index da4ac7450d..44c972462a 100644 --- a/shared/src/com/vaadin/shared/ApplicationConstants.java +++ b/shared/src/com/vaadin/shared/ApplicationConstants.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -78,6 +78,14 @@ public class ApplicationConstants implements Serializable { public static final String VAADIN_DIR_URL = "vaadinDir"; /** + * The name of the javascript containing the bootstrap code. The file is + * located in the VAADIN directory. + * + * @since 7.3 + */ + public static final String VAADIN_BOOTSTRAP_JS = "vaadinBootstrap.js"; + + /** * The name of the javascript containing push support. The file is located * in the VAADIN directory. */ @@ -86,7 +94,7 @@ public class ApplicationConstants implements Serializable { /** * The name of the debug version of the javascript containing push support. * The file is located in the VAADIN directory. - * + * * @since 7.1.6 */ public static final String VAADIN_PUSH_DEBUG_JS = "vaadinPush.debug.js"; @@ -98,14 +106,14 @@ public class ApplicationConstants implements Serializable { /** * The name of the parameter used to transmit RPC invocations - * + * * @since 7.2 */ public static final String RPC_INVOCATIONS = "rpc"; /** * The name of the parameter used to transmit the CSRF token - * + * * @since 7.2 */ public static final String CSRF_TOKEN = "csrfToken"; @@ -114,9 +122,15 @@ public class ApplicationConstants implements Serializable { * The name of the parameter used to transmit the sync id. The value can be * set to -1 e.g. when testing with pre-recorded requests to make the * framework ignore the sync id. - * + * * @see com.vaadin.ui.ConnectorTracker#getCurrentSyncId() * @since 7.2 */ public static final String SERVER_SYNC_ID = "syncId"; + + /** + * Default value to use in case the security protection is disabled. + */ + public static final String CSRF_TOKEN_DEFAULT_VALUE = "init"; + } diff --git a/shared/src/com/vaadin/shared/VBrowserDetails.java b/shared/src/com/vaadin/shared/VBrowserDetails.java index 3680e4168e..81a39cdedc 100644 --- a/shared/src/com/vaadin/shared/VBrowserDetails.java +++ b/shared/src/com/vaadin/shared/VBrowserDetails.java @@ -68,19 +68,19 @@ public class VBrowserDetails implements Serializable { isGecko = userAgent.indexOf("gecko") != -1 && userAgent.indexOf("webkit") == -1 && userAgent.indexOf("trident/") == -1; - isWebKit = userAgent.indexOf("applewebkit") != -1; isPresto = userAgent.indexOf(" presto/") != -1; isTrident = userAgent.indexOf("trident/") != -1; + isWebKit = !isTrident && userAgent.indexOf("applewebkit") != -1; // browser name isChrome = userAgent.indexOf(" chrome/") != -1; - isSafari = !isChrome && userAgent.indexOf("safari") != -1; isOpera = userAgent.indexOf("opera") != -1; isIE = userAgent.indexOf("msie") != -1 && !isOpera && (userAgent.indexOf("webtv") == -1); // IE 11 no longer contains MSIE in the user agent isIE = isIE || isTrident; + isSafari = !isChrome && !isIE && userAgent.indexOf("safari") != -1; isFirefox = userAgent.indexOf(" firefox/") != -1; // chromeframe diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 3c3785b7d5..2f51fef6ee 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -62,6 +62,12 @@ public class UIState extends TabIndexState { * Configuration for the push channel */ public PushConfigurationState pushConfiguration = new PushConfigurationState(); + /** + * Currently used theme. + * + * @since 7.3 + */ + public String theme; { primaryStyleName = "v-ui"; // Default is 1 for legacy reasons @@ -95,7 +101,7 @@ public class UIState extends TabIndexState { NotificationRole role) { this.prefix = prefix; this.postfix = postfix; - this.notificationRole = role; + notificationRole = role; } } diff --git a/shared/src/com/vaadin/shared/util/SharedUtil.java b/shared/src/com/vaadin/shared/util/SharedUtil.java index 497a8cab01..7276f418fa 100644 --- a/shared/src/com/vaadin/shared/util/SharedUtil.java +++ b/shared/src/com/vaadin/shared/util/SharedUtil.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -19,17 +19,17 @@ import java.io.Serializable; /** * Misc internal utility methods used by both the server and the client package. - * + * * @author Vaadin Ltd * @since 7.1 - * + * */ public class SharedUtil implements Serializable { /** * Checks if a and b are equals using {@link #equals(Object)}. Handles null * values as well. Does not ensure that objects are of the same type. * Assumes that the first object's equals method handle equals properly. - * + * * @param o1 * The first value to compare * @param o2 @@ -46,11 +46,18 @@ public class SharedUtil implements Serializable { /** * Trims trailing slashes (if any) from a string. - * @param value The string value to be trimmed. Cannot be null. + * + * @param value + * The string value to be trimmed. Cannot be null. * @return String value without trailing slashes. */ public static String trimTrailingSlashes(String value) { return value.replaceAll("/*$", ""); } + /** + * RegEx pattern to extract the width/height values. + */ + public static final String SIZE_PATTERN = "^(-?\\d*(?:\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$"; + } diff --git a/uitest/build.xml b/uitest/build.xml index 84f44a2d72..e81983f1f5 100644 --- a/uitest/build.xml +++ b/uitest/build.xml @@ -11,6 +11,7 @@ <property name="module.name" value="vaadin-uitest" /> <property name="uitest.dir" location="${vaadin.basedir}/uitest" /> <property name="result.dir" value="result" /> + <property name="theme.result.dir" value="${result.dir}/VAADIN/themes" /> <property name="result.war" location="${result.dir}/lib/${module.name}-${vaadin.version}.war" /> <path id="classpath.compile.custom"> @@ -91,7 +92,7 @@ </target> - <target name="war" depends="dependencies, compile, testing-widgetset"> + <target name="war" depends="dependencies, compile, compile-test-themes, testing-widgetset"> <property name="result.dir" location="result" /> <property name="classes" location="${result.dir}/classes" /> <property name="WebContent.dir" location="${vaadin.basedir}/WebContent" /> @@ -121,10 +122,13 @@ <fileset refid="common.files.for.all.jars" /> <fileset dir="${result.dir}"> <include name="VAADIN/widgetsets/**/*" /> + <include name="VAADIN/themes/tests-valo*/**" /> </fileset> <fileset dir="${WebContent.dir}"> <include name="statictestfiles/**" /> <include name="VAADIN/themes/tests-*/**" /> + <!-- Scss themes compiled and included above --> + <exclude name="VAADIN/themes/tests-valo*/**" /> <include name="VAADIN/themes/reindeer-tests/**" /> <include name="VAADIN/jquery.atmosphere.js" /> <include name="WEB-INF/*.xml" /> @@ -192,43 +196,43 @@ </target> <target name="test-server" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> - <parallel> - <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> - </daemons> - <sequential> - <ant antfile="${uitest.dir}/integration_tests.xml" target="integration-test-all" inheritall="false" inheritrefs="false"> - <property name="demo.war" value="${war.file}" /> - </ant> - </sequential> - </parallel> + <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <parallel> + <daemons> + <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + </daemons> + <sequential> + <ant antfile="${uitest.dir}/integration_tests.xml" target="integration-test-all" inheritall="false" inheritrefs="false"> + <property name="demo.war" value="${war.file}" /> + </ant> + </sequential> + </parallel> </target> <target name="test-tb2" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> - <parallel> - <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> - </daemons> - <sequential> - <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> - <ant antfile="${uitest.dir}/test.xml" target="tb2-tests" /> - </sequential> - </parallel> + <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <parallel> + <daemons> + <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + </daemons> + <sequential> + <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> + <ant antfile="${uitest.dir}/test.xml" target="tb2-tests" /> + </sequential> + </parallel> </target> <target name="test-tb3" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> - <parallel> - <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> - </daemons> - <sequential> - <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> - <ant antfile="${uitest.dir}/tb3test.xml" target="run-all-tb3-tests" inheritall="true" /> - </sequential> - </parallel> + <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <parallel> + <daemons> + <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + </daemons> + <sequential> + <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> + <ant antfile="${uitest.dir}/tb3test.xml" target="run-all-tb3-tests" inheritall="true" /> + </sequential> + </parallel> </target> <target name="clean-testbench-errors"> @@ -241,4 +245,71 @@ </delete> </target> + <target name="compile-test-themes"> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-dark" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-metro" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-flat" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-flatdark" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-facebook" /> + </antcall> + <antcall target="compile-theme"> + <param name="theme" value="tests-valo-blueprint" /> + </antcall> + + </target> + <target name="compile-theme" depends="copy-theme"> + <fail unless="theme" message="You must give the theme name to compile in the 'theme' parameter" /> + + <ivy:resolve log="download-only" resolveid="common" conf="compile-theme" /> + <ivy:cachepath pathid="classpath.compile.theme" conf="compile-theme" /> + <ivy:cachepath pathid="classpath.runtime.theme" conf="build" /> + + <echo>Compiling ${theme}</echo> + <mkdir dir="${theme.result.dir}" /> + + <!-- compile the theme --> + <java classname="com.vaadin.buildhelpers.CompileTheme" classpathref="classpath.compile.theme" failonerror="yes" fork="yes" maxmemory="512m"> + <arg value="--theme" /> + <arg value="${theme}" /> + <arg value="--theme-folder" /> + <arg value="${theme.result.dir}" /> + <arg value="--version" /> + <arg value="${vaadin.version}" /> + <jvmarg value="-Xss8M" /> + <jvmarg value="-XX:MaxPermSize=256M" /> + <jvmarg value="-Djava.awt.headless=true" /> + </java> + + </target> + + <target name="copy-theme"> + <fail unless="theme" message="You must give the theme name to copy n the 'theme' parameter" /> + <property name="theme.source.dir" location="../WebContent/VAADIN/themes" /> + + <copy todir="${theme.result.dir}"> + <fileset dir="${theme.source.dir}"> + <include name="${theme}/**/*.scss" /> + </fileset> + <filterset refid="filter-vaadin.version" /> + </copy> + <copy todir="${theme.result.dir}"> + <fileset dir="${theme.source.dir}"> + <exclude name="${theme}/**/*.scss" /> + </fileset> + </copy> + </target> + + </project> diff --git a/uitest/eclipse-run-selected-test.properties b/uitest/eclipse-run-selected-test.properties index cbd1ab1cef..70010fd1da 100644 --- a/uitest/eclipse-run-selected-test.properties +++ b/uitest/eclipse-run-selected-test.properties @@ -1,4 +1,11 @@ ; +; This is an example property file showing how to control how TestBench is used +; in the Vaadin Framework project. You should not modify this file since it's +; under version control. Instead, create a copy of it inside the /work/ folder +; in the project and make your customizations to that file. +; + +; ; For both TestBench 2 and 3 ; @@ -8,6 +15,14 @@ com.vaadin.testbench.screenshot.directory=<enter the full path to the screenshot ; +; For only TestBench 3 +; + +; Simulates @RunLocally with the given value on all test classes without a @RunLocally annotation. +; com.vaadin.testbench.runLocally=firefox + + +; ; For only TestBench 2 ; diff --git a/uitest/ivy.xml b/uitest/ivy.xml index 020543c53f..9af209662c 100644 --- a/uitest/ivy.xml +++ b/uitest/ivy.xml @@ -15,6 +15,7 @@ <conf name="build-provided" visibility="private" /> <conf name="ide" visibility="private" /> <conf name="jetty-run" visibility="private" /> + <conf name="compile-theme" visibility="private" /> </configurations> <publications> <artifact type="war" ext="war" /> @@ -99,6 +100,13 @@ <!-- This should be removed once tests have been updated to use lang3 --> <dependency org="commons-lang" name="commons-lang" rev="2.6" conf="build,ide -> default" /> + + <dependency org="com.vaadin" name="vaadin-sass-compiler" + rev="${vaadin.sass.version}" conf="compile-theme->default" /> + + <dependency org="com.vaadin" name="vaadin-buildhelpers" + rev="${vaadin.version}" conf="compile-theme->build" /> + </dependencies> </ivy-module> diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index a89ec4e587..1f72495596 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -17,12 +17,17 @@ package com.vaadin.launcher; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; @@ -30,7 +35,11 @@ import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import com.vaadin.launcher.CustomDeploymentConfiguration.Conf; +import com.vaadin.server.DefaultDeploymentConfiguration; +import com.vaadin.server.DeploymentConfiguration; import com.vaadin.server.LegacyApplication; import com.vaadin.server.LegacyVaadinServlet; import com.vaadin.server.ServiceException; @@ -43,6 +52,7 @@ import com.vaadin.server.VaadinServletRequest; import com.vaadin.server.VaadinSession; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.UI; +import com.vaadin.util.CurrentInstance; @SuppressWarnings("serial") public class ApplicationRunnerServlet extends LegacyVaadinServlet { @@ -287,4 +297,129 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { return Logger.getLogger(ApplicationRunnerServlet.class.getName()); } + @Override + protected DeploymentConfiguration createDeploymentConfiguration( + Properties initParameters) { + // Get the original configuration from the super class + final DeploymentConfiguration originalConfiguration = super + .createDeploymentConfiguration(initParameters); + + // And then create a proxy instance that delegates to the original + // configuration or a customized version + return (DeploymentConfiguration) Proxy.newProxyInstance( + DeploymentConfiguration.class.getClassLoader(), + new Class[] { DeploymentConfiguration.class }, + new InvocationHandler() { + @Override + public Object invoke(Object proxy, Method method, + Object[] args) throws Throwable { + if (method.getDeclaringClass() == DeploymentConfiguration.class) { + // Find the configuration instance to delegate to + DeploymentConfiguration configuration = findDeploymentConfiguration(originalConfiguration); + + return method.invoke(configuration, args); + } else { + return method.invoke(proxy, args); + } + } + }); + } + + private DeploymentConfiguration findDeploymentConfiguration( + DeploymentConfiguration originalConfiguration) throws Exception { + // First level of cache + DeploymentConfiguration configuration = CurrentInstance + .get(DeploymentConfiguration.class); + + if (configuration == null) { + // Not in cache, try to find a VaadinSession to get it from + VaadinSession session = VaadinSession.getCurrent(); + + if (session == null) { + /* + * There's no current session, request or response when serving + * static resources, but there's still the current request + * maintained by AppliationRunnerServlet, and there's most + * likely also a HttpSession containing a VaadinSession for that + * request. + */ + + HttpServletRequest currentRequest = request.get(); + if (currentRequest != null) { + HttpSession httpSession = currentRequest.getSession(false); + if (httpSession != null) { + Map<Class<?>, CurrentInstance> oldCurrent = CurrentInstance + .setCurrent((VaadinSession) null); + try { + session = getService().findVaadinSession( + new VaadinServletRequest(currentRequest, + getService())); + } finally { + /* + * Clear some state set by findVaadinSession to + * avoid accidentally depending on it when coding on + * e.g. static request handling. + */ + CurrentInstance.restoreInstances(oldCurrent); + currentRequest.removeAttribute(VaadinSession.class + .getName()); + } + } + } + } + + if (session != null) { + String name = ApplicationRunnerServlet.class.getName() + + ".deploymentConfiguration"; + try { + session.lock(); + configuration = (DeploymentConfiguration) session + .getAttribute(name); + + if (configuration == null) { + Class<?> classToRun; + try { + classToRun = getClassToRun(); + } catch (ClassNotFoundException e) { + /* + * This happens e.g. if the UI class defined in the + * URL is not found or if this servlet just serves + * static resources while there's some other servlet + * that serves the UI (e.g. when using /run-push/). + */ + return originalConfiguration; + } + + CustomDeploymentConfiguration customDeploymentConfiguration = classToRun + .getAnnotation(CustomDeploymentConfiguration.class); + if (customDeploymentConfiguration != null) { + Properties initParameters = new Properties( + originalConfiguration.getInitParameters()); + + for (Conf entry : customDeploymentConfiguration + .value()) { + initParameters.put(entry.name(), entry.value()); + } + + configuration = new DefaultDeploymentConfiguration( + getClass(), initParameters); + } else { + configuration = originalConfiguration; + } + + session.setAttribute(name, configuration); + } + } finally { + session.unlock(); + } + + CurrentInstance.set(DeploymentConfiguration.class, + configuration); + + } else { + configuration = originalConfiguration; + } + } + return configuration; + } } diff --git a/uitest/src/com/vaadin/launcher/CustomDeploymentConfiguration.java b/uitest/src/com/vaadin/launcher/CustomDeploymentConfiguration.java new file mode 100644 index 0000000000..da903c13e0 --- /dev/null +++ b/uitest/src/com/vaadin/launcher/CustomDeploymentConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.launcher; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CustomDeploymentConfiguration { + + @Target(value = ElementType.TYPE) + @Retention(RetentionPolicy.RUNTIME) + public @interface Conf { + public String name(); + + public String value(); + } + + public CustomDeploymentConfiguration.Conf[] value(); +} diff --git a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html deleted file mode 100644 index 40ac075d53..0000000000 --- a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.html +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.VerifyAssertionsEnabled?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsVerifyAssertionsEnabled::/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]</td> - <td>Assertions are enabled</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java index 84ea3a0def..aa757e5f24 100644 --- a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java +++ b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabled.java @@ -17,18 +17,17 @@ package com.vaadin.tests; import com.vaadin.server.VaadinRequest; -import com.vaadin.tests.components.AbstractTestUI; -import com.vaadin.ui.Label; +import com.vaadin.tests.components.AbstractTestUIWithLog; -public class VerifyAssertionsEnabled extends AbstractTestUI { +public class VerifyAssertionsEnabled extends AbstractTestUIWithLog { @Override protected void setup(VaadinRequest request) { try { assert false; - addComponent(new Label("Assertions are not enabled")); + log("Assertions are not enabled"); } catch (AssertionError e) { - addComponent(new Label("Assertions are enabled")); + log("Assertions are enabled"); } } diff --git a/uitest/src/com/vaadin/tests/VerifyAssertionsEnabledTest.java b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabledTest.java new file mode 100644 index 0000000000..1180cc8332 --- /dev/null +++ b/uitest/src/com/vaadin/tests/VerifyAssertionsEnabledTest.java @@ -0,0 +1,14 @@ +package com.vaadin.tests; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class VerifyAssertionsEnabledTest extends SingleBrowserTest { + @Test + public void verifyServerAssertions() throws Exception { + openTestURL(); + Assert.assertEquals("1. Assertions are enabled", getLogRow(0)); + } +} diff --git a/uitest/src/com/vaadin/tests/VerifyJreVersionTest.java b/uitest/src/com/vaadin/tests/VerifyJreVersionTest.java index 0203423787..b78a4ad314 100644 --- a/uitest/src/com/vaadin/tests/VerifyJreVersionTest.java +++ b/uitest/src/com/vaadin/tests/VerifyJreVersionTest.java @@ -21,9 +21,9 @@ import static org.hamcrest.core.Is.is; import org.junit.Test; import org.openqa.selenium.WebElement; -import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.SingleBrowserTest; -public class VerifyJreVersionTest extends MultiBrowserTest { +public class VerifyJreVersionTest extends SingleBrowserTest { @Test public void verifyJreVersion() { diff --git a/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java new file mode 100644 index 0000000000..2ab6be25ac --- /dev/null +++ b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRoles.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.accessibility; + +import java.util.Stack; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.window.WindowRole; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Window; + +/** + * UI to test if subwindows get the correct assistive roles. + * + * @author Vaadin Ltd + */ +public class WindowWaiAriaRoles extends AbstractTestUI { + Stack<Window> windows = new Stack<Window>(); + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + Button closeButton = new Button("Close windows"); + closeButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + while (!windows.isEmpty()) { + Window window = windows.pop(); + removeWindow(window); + } + } + + }); + + Button regularButton = new Button("Regular"); + regularButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Window regularWindow = new Window("Regular window"); + openWindow(regularWindow); + } + }); + + Button alertButton = new Button("Alert"); + alertButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + Window alertWindow = new Window("Alert window"); + alertWindow.setAssistiveRole(WindowRole.ALERTDIALOG); + openWindow(alertWindow); + } + }); + addComponent(closeButton); + addComponent(regularButton); + addComponent(alertButton); + } + + void openWindow(Window window) { + windows.push(window); + window.center(); + addWindow(window); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "The alert window should have the role 'alertdialog' and the regular window should have the role 'dialog'"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14289; + } + +} diff --git a/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java new file mode 100644 index 0000000000..e1d0452708 --- /dev/null +++ b/uitest/src/com/vaadin/tests/accessibility/WindowWaiAriaRolesTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.accessibility; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.WindowElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if regular and alert windows get the correct wai-aria roles + * + * @author Vaadin Ltd + */ +public class WindowWaiAriaRolesTest extends MultiBrowserTest { + + @Test + public void testRegularWindowRole() { + openTestURL(); + + $(ButtonElement.class).caption("Regular").first().click(); + String role = getWindowRole(); + Assert.assertTrue("Dialog has incorrect role '" + role + + "', expected 'dialog'", "dialog".equals(role)); + } + + @Test + public void testAlertWindowRole() { + openTestURL(); + $(ButtonElement.class).caption("Alert").first().click(); + String role = getWindowRole(); + Assert.assertTrue("Dialog has incorrect role '" + role + + "', expected 'alertdialog'", "alertdialog".equals(role)); + } + + public String getWindowRole() { + return $(WindowElement.class).first().getAttribute("role"); + } +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConf.java b/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConf.java new file mode 100644 index 0000000000..8ae7715a77 --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConf.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.applicationservlet; + +import com.vaadin.launcher.ApplicationRunnerServlet; +import com.vaadin.launcher.CustomDeploymentConfiguration; +import com.vaadin.launcher.CustomDeploymentConfiguration.Conf; +import com.vaadin.server.DeploymentConfiguration; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +@CustomDeploymentConfiguration({ + @Conf(name = "customParam", value = "customValue"), + @Conf(name = "resourceCacheTime", value = "3599") }) +public class CustomDeploymentConf extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + DeploymentConfiguration deploymentConfiguration = getSession() + .getService().getDeploymentConfiguration(); + addComponent(new Label("Resource cache time: " + + deploymentConfiguration.getResourceCacheTime())); + addComponent(new Label("Custom config param: " + + deploymentConfiguration.getApplicationOrSystemProperty( + "customParam", null))); + } + + @Override + protected String getTestDescription() { + return "Demonstrates the @" + + CustomDeploymentConfiguration.class.getSimpleName() + + " feature that allows customizing the effective deployment configuration for test UIs run through " + + ApplicationRunnerServlet.class.getSimpleName() + "."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(14215); + } + +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConfTest.java b/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConfTest.java new file mode 100644 index 0000000000..e74eea6c55 --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationservlet/CustomDeploymentConfTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.applicationservlet; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.VerticalLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class CustomDeploymentConfTest extends MultiBrowserTest { + @Test + public void testCustomDeploymentConf() { + openTestURL(); + + LabelElement cacheTimeLabel = $$(VerticalLayoutElement.class) + .$$(VerticalLayoutElement.class).$$(LabelElement.class).first(); + + LabelElement customParamLabel = $$(VerticalLayoutElement.class) + .$$(VerticalLayoutElement.class).$$(LabelElement.class).get(1); + + Assert.assertEquals("Resource cache time: 3599", + cacheTimeLabel.getText()); + Assert.assertEquals("Custom config param: customValue", + customParamLabel.getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java b/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java index ce99c4a3d5..8500fbe18d 100644 --- a/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java +++ b/uitest/src/com/vaadin/tests/components/abstractcomponent/PrimaryStyleTest.java @@ -43,7 +43,8 @@ public class PrimaryStyleTest extends MultiBrowserTest { $(ButtonElement.class).id("update-button").click(); // Verify that the class names where updated as expected. - List<WebElement> updatedElements = driver.findElements(By.className("updated-correctly")); + List<WebElement> updatedElements = driver.findElements(By + .className("updated-correctly")); assertThat(updatedElements, hasSize(initialElements.size())); } diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java b/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java index 25dd469903..cee71fdf4e 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonToggleIcons.java @@ -35,4 +35,4 @@ public class ButtonToggleIcons extends UI { layout.addComponent(new Button("Toggle icon", iconToggleListener));
layout.addComponent(new NativeButton("Toggle icon", iconToggleListener));
}
-} +}
diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonTooltips.html b/uitest/src/com/vaadin/tests/components/button/ButtonTooltips.html deleted file mode 100644 index 13fdf52c76..0000000000 --- a/uitest/src/com/vaadin/tests/components/button/ButtonTooltips.html +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://192.168.2.168:8888/" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.button.ButtonTooltips?restartApplication</td> - <td></td> -</tr> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonTooltips::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonTooltips::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html deleted file mode 100644 index 0aaa01f05b..0000000000 --- a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.html +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>ButtonUndefinedWidth</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">ButtonUndefinedWidth</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.button.ButtonUndefinedWidth</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VNativeButton[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VNativeButton[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentsbuttonButtonUndefinedWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[2]</td> - <td>636,149</td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java index 89b03df92a..e8a2e10d9a 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidth.java @@ -1,15 +1,22 @@ package com.vaadin.tests.components.button; import com.vaadin.data.Item; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.NativeButton; import com.vaadin.ui.Table; -public class ButtonUndefinedWidth extends TestBase { +/** + * Test UI for buttons with undefined width. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class ButtonUndefinedWidth extends AbstractTestUI { @Override - protected String getDescription() { + protected String getTestDescription() { return "Both the button outside the table and inside the table should be only as wide as necessary. There should be empty space in the table to the right of the button."; } @@ -18,8 +25,9 @@ public class ButtonUndefinedWidth extends TestBase { return 3257; } + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { Button b = new Button("Undefined wide"); addComponent(b); NativeButton b2 = new NativeButton("Undefined wide"); @@ -36,5 +44,4 @@ public class ButtonUndefinedWidth extends TestBase { addComponent(t); } - } diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java new file mode 100644 index 0000000000..850dd1229c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/button/ButtonUndefinedWidthTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.button; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeButtonElement; +import com.vaadin.testbench.elements.VerticalLayoutElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Validates button Widths for Buttons or Native Buttons, inside or outside + * tables. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class ButtonUndefinedWidthTest extends MultiBrowserTest { + + @Test + public void undefinedButtonWidthTest() throws Exception { + openTestURL(); + + // make sure all the elements are rendered before commencing tests + waitForElementVisible(By.className("v-table-row-odd")); + + // click all of the buttons + for (NativeButtonElement button : $(NativeButtonElement.class).all()) { + button.click(); + } + for (ButtonElement button : $(ButtonElement.class).all()) { + button.click(); + } + + // remove focus + getDriver().findElement(By.className("v-app")).click(); + + // check button widths in VerticalLayout + VerticalLayoutElement vLayout = $(VerticalLayoutElement.class).$( + VerticalLayoutElement.class).first(); + int containerWidth = vLayout.getSize().getWidth(); + + NativeButtonElement nativeButton = vLayout.$(NativeButtonElement.class) + .first(); + int buttonWidth = nativeButton.getSize().getWidth(); + + assertButtonWidth(buttonWidth, containerWidth); + + ButtonElement button = vLayout.$(ButtonElement.class).first(); + buttonWidth = button.getSize().getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + // check button widths in table, also make sure that there is some + // spacing between the table edges and buttons + List<WebElement> rows = findElements(By + .className("v-table-cell-content")); + int rowWidth = rows.get(0).getSize().getWidth(); + + List<WebElement> rowWrappers = findElements(By + .className("v-table-cell-wrapper")); + WebElement row = rowWrappers.get(0); + + containerWidth = row.getSize().getWidth(); + assertRowWrapperWidth(containerWidth, rowWidth); + + buttonWidth = row.findElement(By.className("v-button")).getSize() + .getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + row = rowWrappers.get(1); + containerWidth = row.getSize().getWidth(); + assertRowWrapperWidth(containerWidth, rowWidth); + + buttonWidth = row.findElement(By.className("v-nativebutton")).getSize() + .getWidth(); + assertButtonWidth(buttonWidth, containerWidth); + + } + + private void assertRowWrapperWidth(int wrapperWidth, int rowWidth) { + Assert.assertTrue("Wrapper should be narrower than its parent: " + + wrapperWidth + " < " + rowWidth, wrapperWidth < rowWidth); + } + + private void assertButtonWidth(int buttonWidth, int containerWidth) { + Assert.assertTrue("Button should be narrower than its parent: " + + buttonWidth + " < " + containerWidth, + buttonWidth < containerWidth); + } +} diff --git a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java index 9d6640eb6d..69a919497b 100644 --- a/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java +++ b/uitest/src/com/vaadin/tests/components/checkbox/CheckBoxRpcCountTest.java @@ -40,7 +40,7 @@ public class CheckBoxRpcCountTest extends MultiBrowserTest { // Click on the actual checkbox. inputElem.click(); - //Have to use waitUntil to make this test more stable. + // Have to use waitUntil to make this test more stable. waitUntilLabelIsUpdated(countElem, "1 RPC call(s) made."); // Click on the checkbox label. @@ -52,7 +52,8 @@ public class CheckBoxRpcCountTest extends MultiBrowserTest { waitUntilLabelIsUpdated(countElem, "3 RPC call(s) made."); } - private void waitUntilLabelIsUpdated(final WebElement countElem, final String expectedText) { + private void waitUntilLabelIsUpdated(final WebElement countElem, + final String expectedText) { waitUntil(new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver input) { diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html deleted file mode 100644 index 3de221871d..0000000000 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxFiltering.html +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.combobox.ComboBoxSlow?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>92,19</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>1</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-no-match</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>Item 12</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-11-matches-paging</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-11-matches-page-2</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSlow::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>Item 100</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>filter-2-matches-no-paging</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html deleted file mode 100644 index 3ad7d62a09..0000000000 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html +++ /dev/null @@ -1,116 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.combobox.ComboBoxIdenticalItems?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>66,8</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>1. Item one-1 selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>2. Item one-2 selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>3. Item two selected</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>up</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>enter</td> -</tr> -<tr> - <td>pause</td> - <td>100</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td> - <td>4. Item one-1 selected</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java index 5f33b96a73..cdae1c8e38 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.java @@ -3,16 +3,18 @@ package com.vaadin.tests.components.combobox; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.util.Log; import com.vaadin.ui.ComboBox; -public class ComboBoxIdenticalItems extends TestBase { +public class ComboBoxIdenticalItems extends AbstractTestUI { private Log log = new Log(5); + @SuppressWarnings("unchecked") @Override - public void setup() { + protected void setup(VaadinRequest request) { final ComboBox select = new ComboBox("ComboBox"); select.addContainerProperty("caption", String.class, null); Item item = select.addItem("one-1"); @@ -24,9 +26,7 @@ public class ComboBoxIdenticalItems extends TestBase { select.setItemCaptionPropertyId("caption"); select.setNullSelectionAllowed(false); select.setImmediate(true); - select.addListener(new Property.ValueChangeListener() { - private static final long serialVersionUID = -7932700771673919620L; - + select.addValueChangeListener(new Property.ValueChangeListener() { @Override public void valueChange(ValueChangeEvent event) { log.log("Item " + select.getValue() + " selected"); @@ -39,7 +39,7 @@ public class ComboBoxIdenticalItems extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Keyboard selecting of a value is broken in combobox if two " + "items have the same caption. The first item's id is \"One-1\" " + "while the second one is \"One-2\". Selecting with mouse works " @@ -49,7 +49,6 @@ public class ComboBoxIdenticalItems extends TestBase { @Override protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; + return 6125; } } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java new file mode 100644 index 0000000000..d2cb80ae67 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.combobox; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * @author Vaadin Ltd + */ +public class ComboBoxIdenticalItemsTest extends MultiBrowserTest { + + private WebElement select; + + /* This test has been directly ported from a TB2 test */ + @Test + public void identicalItemsKeyboardTest() throws Exception { + openTestURL(); + + // wait for the UI to be fully loaded + waitForElementVisible(By.className("v-filterselect")); + waitForElementVisible(By.id("Log")); + + select = findElement(By + .vaadin("/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]")); + select.click(); + + Keys[] downDownEnter = new Keys[] { Keys.ARROW_DOWN, Keys.ARROW_DOWN, + Keys.ENTER }; + sendKeys(downDownEnter); + assertLogText("1. Item one-1 selected"); + + sendKeys(downDownEnter); + assertLogText("2. Item one-2 selected"); + + sendKeys(downDownEnter); + assertLogText("3. Item two selected"); + + sendKeys(new Keys[] { Keys.ARROW_UP, Keys.ARROW_UP, Keys.ARROW_UP, + Keys.ENTER }); + assertLogText("4. Item one-1 selected"); + } + + private void assertLogText(String expected) throws Exception { + String text = findElement(By.vaadin("PID_SLog_row_0")).getText(); + Assert.assertTrue("Expected '" + expected + "' found '" + text + "'", + text.equals(expected)); + } + + private void sendKeys(Keys[] keys) throws Exception { + for (Keys key : keys) { + select.sendKeys(key); + // wait a while between the key presses, at least PhantomJS fails if + // they are sent too fast + sleep(10); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java index 96151022ff..cbd83c5734 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxInputPromptTest.java @@ -40,13 +40,16 @@ public class ComboBoxInputPromptTest extends MultiBrowserTest { ComboBoxElement disabledComboBox = getComboBoxWithCaption("Disabled"); ComboBoxElement readOnlyComboBox = getComboBoxWithCaption("Read-only"); - assertThat(getInputPromptValue(normalComboBox), is("Normal input prompt")); + assertThat(getInputPromptValue(normalComboBox), + is("Normal input prompt")); assertThat(getInputPromptValue(disabledComboBox), isEmptyString()); assertThat(getInputPromptValue(readOnlyComboBox), isEmptyString()); toggleDisabledAndReadonly(); - assertThat(getInputPromptValue(disabledComboBox), is("Disabled input prompt")); - assertThat(getInputPromptValue(readOnlyComboBox), is("Read-only input prompt")); + assertThat(getInputPromptValue(disabledComboBox), + is("Disabled input prompt")); + assertThat(getInputPromptValue(readOnlyComboBox), + is("Read-only input prompt")); toggleDisabledAndReadonly(); assertThat(getInputPromptValue(disabledComboBox), isEmptyString()); diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java new file mode 100644 index 0000000000..044214cecf --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreen.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.combobox; + +import com.vaadin.data.Item; +import com.vaadin.server.ClassResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; + +/** + * Test UI for issue #11929 where ComboBox suggestion popup hides the ComboBox + * itself obscuring the text input field. + * + * @author Vaadin Ltd + */ +public class ComboBoxOnSmallScreen extends AbstractTestUI { + + private static final String PID = "captionPID"; + + @Override + protected void setup(VaadinRequest request) { + addComponents(createComboBox()); + } + + @Override + protected String getTestDescription() { + return "Combobox hides what you are typing on small screen"; + } + + @Override + protected Integer getTicketNumber() { + return 11929; + } + + private ComboBox createComboBox() { + ComboBox cb = new ComboBox(); + cb.addContainerProperty(PID, String.class, ""); + cb.setItemCaptionPropertyId(PID); + + Object selectId = null; + + for (int i = 1; i < 22; ++i) { + final String v = "Item #" + i; + Object itemId = cb.addItem(); + + if (i == 9) { + selectId = itemId; + } + + Item item = cb.getItem(itemId); + item.getItemProperty(PID).setValue(v); + int flagIndex = i % 3; + cb.setItemIcon(itemId, new ClassResource( + flagIndex == 0 ? "fi_small.png" : flagIndex == 1 ? "fi.gif" + : "se.gif")); + } + + cb.select(selectId); + + return cb; + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java new file mode 100644 index 0000000000..f48f2bbdeb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxOnSmallScreenTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.combobox; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebDriver.Window; +import org.openqa.selenium.WebElement; + +import com.vaadin.client.ui.VFilterSelect; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * ComboBox suggestion popup should not obscure the text input box. + * + * @author Vaadin Ltd + */ +public class ComboBoxOnSmallScreenTest extends MultiBrowserTest { + + private static final Dimension TARGETSIZE = new Dimension(600, 300); + private static final String POPUPCLASSNAME = VFilterSelect.CLASSNAME + + "-suggestpopup"; + + ComboBoxElement combobox; + WebElement popup; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + + getWindow().setSize(TARGETSIZE); + + combobox = $(ComboBoxElement.class).first(); + combobox.openPopup(); + + popup = findElement(By.className(POPUPCLASSNAME)); + } + + @Test + public void testSuggestionPopupOverlayPosition() { + final int popupTop = popup.getLocation().y; + final int popupBottom = popupTop + popup.getSize().getHeight(); + final int cbTop = combobox.getLocation().y; + final int cbBottom = cbTop + combobox.getSize().getHeight(); + + assertThat("Popup overlay overlaps with the textbox", + popupTop >= cbBottom || popupBottom <= cbTop, is(true)); + } + + @Test + public void testSuggestionPopupOverlaySize() { + final int popupTop = popup.getLocation().y; + final int popupBottom = popupTop + popup.getSize().getHeight(); + final int rootHeight = findElement(By.tagName("body")).getSize().height; + + assertThat("Popup overlay out of the screen", popupTop < 0 + || popupBottom > rootHeight, is(false)); + } + + private Window getWindow() { + return getDriver().manage().window(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java index fa6f5a3a93..bc1fe39fe5 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java @@ -52,8 +52,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { // provide any way to access the popup and send keys to it. // Ticket #13756 - return driver.findElement(By - .className("v-filterselect-input")); + return driver.findElement(By.className("v-filterselect-input")); } private void openPopup() { @@ -70,7 +69,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { dropDownComboBox.sendKeys(Keys.DOWN); } - assertThat(getSelectedItemText(), is("item " + PAGESIZE)); //item 10 + assertThat(getSelectedItemText(), is("item " + PAGESIZE)); // item 10 } private String getSelectedItemText() { @@ -92,7 +91,8 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { waitUntilNextPageIsVisible(); dropDownComboBox.sendKeys(Keys.UP); - assertThat(getSelectedItemText(), is("item " + (PAGESIZE - 1))); //item 9 + assertThat(getSelectedItemText(), is("item " + (PAGESIZE - 1))); // item + // 9 } private void waitUntilNextPageIsVisible() { diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java new file mode 100644 index 0000000000..f030c0f5a0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSlowTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.combobox; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Verifies SlowComboBox filtering works when user inputs text. Also verifies + * pagination works when the matching results number more than those that can be + * displayed. + * + * @since + * @author Vaadin Ltd + */ +public class ComboBoxSlowTest extends MultiBrowserTest { + + @Before + public void init() { + openTestURL(); + } + + @Test + public void testZeroMatches() throws InterruptedException { + clickComboBoxTextArea(); + sleep(250); + typeString("1"); + assertEquals(0, getNumberOfSuggestions()); + } + + @Test + public void testElevenMatchesAndPaging() throws InterruptedException { + clickComboBoxTextArea(); + sleep(250); + typeString("Item 12"); + + assertEquals(10, getNumberOfSuggestions()); + assertTrue(isPagingActive()); + goToNextPage(); + + sleep(500); + assertEquals(1, getNumberOfSuggestions()); + + } + + @Test + public void testTwoMatchesNoPaging() { + clickComboBoxTextArea(); + typeString("Item 100"); + assertEquals(2, getNumberOfSuggestions()); + assertFalse(isPagingActive()); + } + + private void clickComboBoxTextArea() { + WebElement cb = getDriver().findElement( + By.className("v-filterselect-input")); + cb.click(); + } + + private void typeString(String s) { + Actions action = new Actions(getDriver()); + action.sendKeys(s); + action.build().perform(); + } + + private int getNumberOfSuggestions() { + + List<WebElement> elements = getDriver().findElements( + By.className("gwt-MenuItem")); + return elements.size(); + } + + private boolean isPagingActive() { + List<WebElement> elements = getDriver().findElements( + By.className("v-filterselect-nextpage")); + return elements.size() == 1; + } + + private void goToNextPage() { + WebElement nextPage = getDriver().findElement( + By.className("v-filterselect-nextpage")); + nextPage.click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupClose.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupClose.java new file mode 100644 index 0000000000..253d6a0d1e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupClose.java @@ -0,0 +1,29 @@ +package com.vaadin.tests.components.combobox; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; + +public class ComboBoxSuggestionPopupClose extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final ComboBox select = new ComboBox("ComboBox"); + select.addItem("one"); + select.addItem("two"); + select.addItem("three"); + addComponent(select); + } + + @Override + protected String getTestDescription() { + return "Closing the suggestion popup using Enter key is " + + "broken in combobox when opening popup using Enter " + + "key and not changin the selection using arrows"; + } + + @Override + protected Integer getTicketNumber() { + return 14379; + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupCloseTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupCloseTest.java new file mode 100644 index 0000000000..5e9e076cac --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSuggestionPopupCloseTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.combobox; + +import static org.junit.Assert.assertFalse; +import static org.openqa.selenium.Keys.ARROW_DOWN; +import static org.openqa.selenium.Keys.ENTER; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * @author Vaadin Ltd + */ +public class ComboBoxSuggestionPopupCloseTest extends MultiBrowserTest { + + private WebElement selectTextbox; + + @Test + public void closeSuggestionPopupTest() throws Exception { + openTestURL(); + + waitForElementVisible(By.className("v-filterselect")); + + selectTextbox = $(ComboBoxElement.class).first().findElement( + By.vaadin("#textbox")); + selectTextbox.click(); + + // open popup and select first element + sendKeys(new Keys[] { ARROW_DOWN, ARROW_DOWN, ENTER }); + + // open popup and hit enter to close it + sendKeys(new Keys[] { ARROW_DOWN, ENTER }); + + assertFalse(isElementPresent(By.className("v-filterselect-suggestmenu"))); + + } + + private void sendKeys(Keys[] keys) throws Exception { + for (Keys key : keys) { + selectTextbox.sendKeys(key); + // wait a while between the key presses, at least PhantomJS fails if + // they are sent too fast + sleep(10); + } + } +}; diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html index ae0dfec828..8366f2dc8c 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxUndefinedWidthAndIcon.html @@ -1,3 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> <tr> <td>open</td> <td>/run/com.vaadin.tests.components.combobox.ComboBoxUndefinedWidthAndIcon?restartApplication</td> @@ -83,3 +96,6 @@ <td></td> <td>item33-selected-after-popup-opened-and-closed</td> </tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/combobox/fi.png b/uitest/src/com/vaadin/tests/components/combobox/fi.png Binary files differnew file mode 100644 index 0000000000..976a9663ce --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/fi.png diff --git a/uitest/src/com/vaadin/tests/components/combobox/fi_small.png b/uitest/src/com/vaadin/tests/components/combobox/fi_small.png Binary files differnew file mode 100644 index 0000000000..2908973fa4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/fi_small.png diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java new file mode 100644 index 0000000000..9dbd8fa6dc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolution.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.DateField; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.PopupDateField; + +public class DateFieldChangeResolution extends AbstractTestUI { + + public static final String DATEFIELD_ID = "datefield"; + // The ID of a button is BUTTON_BASE_ID + resolution, e.g. button-month + public static final String BUTTON_BASE_ID = "button-"; + + @Override + protected void setup(VaadinRequest request) { + final DateField dateField = new PopupDateField("Enter date"); + dateField.setResolution(Resolution.YEAR); + dateField.setId(DATEFIELD_ID); + dateField.setImmediate(true); + addComponent(dateField); + + Label l = new Label("Select resolution"); + addComponent(l); + HorizontalLayout hlayout = new HorizontalLayout(); + addComponent(hlayout); + for (final Resolution value : Resolution.values()) { + String resolutionString = value.toString().toLowerCase(); + Button b = new Button(resolutionString); + b.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + dateField.setResolution(value); + } + }); + b.setId(BUTTON_BASE_ID + resolutionString); + hlayout.addComponent(b); + } + + } + + @Override + protected String getTestDescription() { + return "The calendar should always have the correct resolution and the text field should be empty before selecting a date."; + } + + @Override + protected Integer getTicketNumber() { + return 14174; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java new file mode 100644 index 0000000000..e3c85224c0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldChangeResolutionTest.java @@ -0,0 +1,200 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.datefield; + +import static com.vaadin.tests.components.datefield.DateFieldChangeResolution.BUTTON_BASE_ID; +import static com.vaadin.tests.components.datefield.DateFieldChangeResolution.DATEFIELD_ID; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldChangeResolutionTest extends MultiBrowserTest { + + private WebElement dateFieldButton, textField; + private WebElement resolutionSecond, resolutionMinute, resolutionHour, + resolutionDay, resolutionMonth, resolutionYear; + + @Test + public void changeResolutionBetweenYearAndMonth() throws Exception { + initialize(); + click(resolutionMonth); + checkHeaderAndBody(Resolution.MONTH, true); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, true); + } + + @Test + public void changeResolutionBetweenYearAndSecond() throws Exception { + initialize(); + click(resolutionSecond); + checkHeaderAndBody(Resolution.SECOND, true); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, true); + } + + @Test + public void changeResolutionToDayThenMonth() throws Exception { + initialize(); + checkHeaderAndBody(Resolution.YEAR, true); // check the initial state + click(resolutionDay); + checkHeaderAndBody(Resolution.DAY, true); + click(resolutionMonth); + checkHeaderAndBody(Resolution.MONTH, true); + } + + @Test + public void setDateAndChangeResolution() throws Exception { + initialize(); + // Set the date to previous month. + click(resolutionMonth); + openPopupDateField(); + click(driver.findElement(By.className("v-button-prevmonth"))); + closePopupDateField(); + assertFalse( + "The text field of the calendar should not be empty after selecting a date", + textField.getAttribute("value").isEmpty()); + // Change resolutions and check that the selected date is not lost and + // that the calendar has the correct resolution. + click(resolutionHour); + checkHeaderAndBody(Resolution.HOUR, false); + click(resolutionYear); + checkHeaderAndBody(Resolution.YEAR, false); + click(resolutionMinute); + checkHeaderAndBody(Resolution.MINUTE, false); + } + + private void initialize() { + openTestURL(); + WebElement dateField = driver.findElement(By.id(DATEFIELD_ID)); + dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + textField = dateField + .findElement(By.className("v-datefield-textfield")); + resolutionSecond = driver.findElement(By.id(BUTTON_BASE_ID + "second")); + resolutionMinute = driver.findElement(By.id(BUTTON_BASE_ID + "minute")); + resolutionHour = driver.findElement(By.id(BUTTON_BASE_ID + "hour")); + resolutionDay = driver.findElement(By.id(BUTTON_BASE_ID + "day")); + resolutionMonth = driver.findElement(By.id(BUTTON_BASE_ID + "month")); + resolutionYear = driver.findElement(By.id(BUTTON_BASE_ID + "year")); + } + + private void checkHeaderAndBody(Resolution resolution, + boolean textFieldIsEmpty) throws Exception { + // Popup date field has all kinds of strange timers on the + // client side + sleep(100); + // Open the popup calendar, perform checks and close the popup. + openPopupDateField(); + if (resolution.getCalendarField() >= Resolution.MONTH + .getCalendarField()) { + checkMonthHeader(); + } else { + checkYearHeader(); + } + if (resolution.getCalendarField() >= Resolution.DAY.getCalendarField()) { + assertTrue( + "A calendar with the chosen resolution should have a body", + calendarHasBody()); + } else { + assertFalse( + "A calendar with the chosen resolution should not have a body", + calendarHasBody()); + } + if (textFieldIsEmpty) { + assertTrue("The text field of the calendar should be empty", + textField.getAttribute("value").isEmpty()); + } else { + assertFalse("The text field of the calendar should not be empty", + textField.getAttribute("value").isEmpty()); + } + closePopupDateField(); + } + + private void checkMonthHeader() { + checkHeaderForYear(); + checkHeaderForMonth(true); + } + + private void checkYearHeader() { + checkHeaderForYear(); + checkHeaderForMonth(false); + } + + private boolean calendarHasBody() { + return isElementPresent(By.className("v-datefield-calendarpanel-body")); + } + + private void checkHeaderForMonth(boolean buttonsExpected) { + // If buttonsExpected is true, check that there are buttons for changing + // the month. Otherwise check that there are no such buttons. + if (buttonsExpected) { + assertTrue( + "The calendar should have a button for switching to the previous month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth"))); + assertTrue( + "The calendar should have a button for switching to the next month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth"))); + } else { + assertFalse( + "The calendar should not have a button for switching to the previous month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevmonth .v-button-prevmonth"))); + assertFalse( + "The calendar should not have a button for switching to the next month", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextmonth .v-button-nextmonth"))); + } + } + + private void checkHeaderForYear() { + assertTrue( + "The calendar should have a button for switching to the previous year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-prevyear .v-button-prevyear"))); + assertTrue( + "The calendar header should show the selected year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-month"))); + assertTrue( + "The calendar should have a button for switching to the next year", + isElementPresent(By + .cssSelector(".v-datefield-calendarpanel-header .v-datefield-calendarpanel-nextyear .v-button-nextyear"))); + + } + + private void click(WebElement element) { + testBenchElement(element).click(5, 5); + } + + private void openPopupDateField() { + click(dateFieldButton); + } + + private void closePopupDateField() { + WebElement element = driver.findElement(By + .cssSelector(".v-datefield-calendarpanel")); + element.sendKeys(Keys.ESCAPE); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.java new file mode 100644 index 0000000000..9ce190a293 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldClose.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DateField; + +public class DateFieldClose extends AbstractTestUI { + + static final String DATEFIELD_ID = "datefield"; + + @Override + protected void setup(VaadinRequest request) { + final DateField df = new DateField(); + df.setId(DATEFIELD_ID); + addComponent(df); + } + + @Override + protected String getTestDescription() { + return "A click on the button should open a calendar and a second click should close it."; + } + + @Override + protected Integer getTicketNumber() { + return 14086; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java new file mode 100644 index 0000000000..e6f7520813 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldCloseTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.datefield; + +import static com.vaadin.tests.components.datefield.DateFieldClose.DATEFIELD_ID; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldCloseTest extends MultiBrowserTest { + private WebElement dateField; + + @Test + public void closeByClickingCalendarButton() throws Exception { + openTestURL(); + dateField = driver.findElement(By.id(DATEFIELD_ID)); + clickButton(); + checkForCalendarHeader(true); + closePopup(); + checkForCalendarHeader(false); + } + + private void checkForCalendarHeader(boolean headerShouldExist) { + boolean headerExists = isElementPresent(By + .className("v-datefield-calendarpanel-header")); + if (headerShouldExist) { + assertTrue("The calendar should be visible", headerExists); + } else { + assertFalse("The calendar should not be visible", headerExists); + } + } + + private void clickButton() { + WebElement dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + testBenchElement(dateFieldButton).click(5, 5); + } + + private void closePopup() { + WebElement dateFieldButton = dateField.findElement(By + .className("v-datefield-button")); + // To work reliably with IE, need to click and hold instead of just + // clicking the button. + Actions actions = new Actions(driver); + actions.clickAndHold(dateFieldButton).perform(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html b/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html index 6e1ca024cb..1135c650f5 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldRanges_MonthChangeMeansFocusDayRolledInsideRange.html @@ -1,3 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> <tr> <td>open</td> <td>/run/com.vaadin.tests.components.datefield.DateFieldRanges</td> @@ -98,3 +111,6 @@ <td>//table[@id='PID_VAADIN_POPUPCAL']/tbody/tr/td[3]/span</td> <td>February 2010</td> </tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java index 289a5988ee..cfab13e205 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldReadOnlyTest.java @@ -1,6 +1,5 @@ package com.vaadin.tests.components.datefield; - import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.DateFieldElement; @@ -14,7 +13,8 @@ import java.io.IOException; public class DateFieldReadOnlyTest extends MultiBrowserTest { @Test - public void readOnlyDateFieldPopupShouldNotOpen() throws IOException, InterruptedException { + public void readOnlyDateFieldPopupShouldNotOpen() throws IOException, + InterruptedException { openTestURL(); compareScreen("initial"); @@ -29,12 +29,15 @@ public class DateFieldReadOnlyTest extends MultiBrowserTest { } private void closePopup() { - findElement(By.className("v-datefield-calendarpanel")).sendKeys(Keys.RETURN); + findElement(By.className("v-datefield-calendarpanel")).sendKeys( + Keys.RETURN); } private void openPopup() { - //waiting for openPopup() in TB4 beta1: http://dev.vaadin.com/ticket/13766 - $(DateFieldElement.class).first().findElement(By.tagName("button")).click(); + // waiting for openPopup() in TB4 beta1: + // http://dev.vaadin.com/ticket/13766 + $(DateFieldElement.class).first().findElement(By.tagName("button")) + .click(); } private void toggleReadOnly() { diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java index eb4888ea1a..95152e1416 100644 --- a/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java +++ b/uitest/src/com/vaadin/tests/components/gridlayout/MoveComponentsFromGridLayoutToInnerLayoutTest.java @@ -9,7 +9,8 @@ import java.io.IOException; import static org.junit.Assert.*; -public class MoveComponentsFromGridLayoutToInnerLayoutTest extends MultiBrowserTest { +public class MoveComponentsFromGridLayoutToInnerLayoutTest extends + MultiBrowserTest { @Test public void buttonIsMovedInsideInnerLayout() throws IOException { diff --git a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html index 4a724795b3..8a042ede92 100644 --- a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html index 9877493b3b..34fb088ff9 100644 --- a/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html +++ b/uitest/src/com/vaadin/tests/components/label/LabelTooltip-runo.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=runo</td> + <td>/run/com.vaadin.tests.components.label.LabelTooltip?restartApplication&theme=runo</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java index bb8f87daaa..24025b9f39 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuTooltipTest.java @@ -47,7 +47,8 @@ public class MenuTooltipTest extends MultiBrowserTest { public void testToolTipDelay() throws InterruptedException { openTestURL(); - Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class).first()); + Coordinates elementCoordinates = getCoordinates($(MenuBarElement.class) + .first()); Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.java new file mode 100644 index 0000000000..b6c80aea0c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClick.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.nativebutton; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeButton; + +/** + * UI used to validate click coordinates reported from clicks on NativeButton + * elements. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class NativeButtonClick extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final Label label1 = new Label("0,0"); + final Label label2 = new Label("0,0"); + + Button button1 = new NativeButton("Button1", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label1.setValue(event.getClientX() + "," + + event.getClientY()); + } + }); + Button button2 = new NativeButton("Button2", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label2.setValue(event.getClientX() + "," + + event.getClientY()); + } + }); + + HorizontalLayout layout = new HorizontalLayout(); + layout.addComponents(button1, button2, label1, label2); + layout.setSpacing(true); + addComponent(layout); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Validate click event coordinates not erroneously returned as x=0, y=0"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14022; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.java new file mode 100644 index 0000000000..cab2acefff --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonClickTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.nativebutton; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if coordinates returned by click event on NativeButtons look + * good. (see #14022) + * + * @author Vaadin Ltd + */ +public class NativeButtonClickTest extends MultiBrowserTest { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() + */ + + @Test + public void testClickCoordinates() { + openTestURL(); + + clickFirstButton(); + String eventCoordinates = getFirstLabelValue(); + Assert.assertNotEquals("0,0", eventCoordinates); + + clickSecondButton(); + eventCoordinates = getSecondLabelValue(); + Assert.assertNotEquals("0,0", eventCoordinates); + } + + private void clickFirstButton() { + ButtonElement button = $(ButtonElement.class).first(); + button.click(); + } + + private void clickSecondButton() { + ButtonElement button = $(ButtonElement.class).get(1); + button.click(); + } + + private String getFirstLabelValue() { + LabelElement label = $(LabelElement.class).get(1); + return label.getText(); + } + + private String getSecondLabelValue() { + LabelElement label = $(LabelElement.class).get(2); + return label.getText(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html deleted file mode 100644 index fb00953e48..0000000000 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>NotificationsWaiAria</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">NotificationsWaiAria</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.notification.NotificationsWaiAria?restartApplication</td> - <td></td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> - <td>Prefix:</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> - <td>- press ESC to close</td> -</tr> -<tr> - <td>select</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> - <td>label=ALERT</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td></td> -</tr> -<tr> - <td>assertAttribute</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]@role</td> - <td>alert</td> -</tr> -<tr> - <td>assertText</td> - <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][1]</td> - <td>Prefix:</td> -</tr> -<tr> - <td>assertText</td> - <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][2]</td> - <td>- press ESC to close</td> -</tr> -<tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>select</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> - <td>label=STATUS</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertAttribute</td> - <td>xpath=/html/body/div[2]/div@role</td> - <td>status</td> -</tr> -<tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>type</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>type</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]/domChild[0]/domChild[0]/domChild[1]</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java index ecf704835f..e85d60d7c2 100644 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java @@ -2,8 +2,9 @@ package com.vaadin.tests.components.notification; import com.vaadin.data.Item; import com.vaadin.server.Page; +import com.vaadin.server.VaadinRequest; import com.vaadin.shared.ui.ui.NotificationRole; -import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; @@ -16,10 +17,15 @@ import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; -public class NotificationsWaiAria extends TestBase { +/** + * Test UI for different roles of Notifications. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class NotificationsWaiAria extends AbstractTestUI { private static final String CAPTION = "CAPTION"; - private static final String ROLE = "ROLE"; private TextField prefix; private TextField postfix; @@ -28,9 +34,9 @@ public class NotificationsWaiAria extends TestBase { private TextArea tf; private ComboBox type; - @SuppressWarnings("deprecation") + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { prefix = new TextField("Prefix", "Info"); addComponent(prefix); @@ -53,16 +59,16 @@ public class NotificationsWaiAria extends TestBase { type.setItemCaptionPropertyId(CAPTION); - Item item = type.addItem(Notification.TYPE_HUMANIZED_MESSAGE); + Item item = type.addItem(Notification.Type.HUMANIZED_MESSAGE); item.getItemProperty(CAPTION).setValue("Humanized"); - item = type.addItem(Notification.TYPE_ERROR_MESSAGE); + item = type.addItem(Notification.Type.ERROR_MESSAGE); item.getItemProperty(CAPTION).setValue("Error"); - item = type.addItem(Notification.TYPE_WARNING_MESSAGE); + item = type.addItem(Notification.Type.WARNING_MESSAGE); item.getItemProperty(CAPTION).setValue("Warning"); - item = type.addItem(Notification.TYPE_TRAY_NOTIFICATION); + item = type.addItem(Notification.Type.TRAY_NOTIFICATION); item.getItemProperty(CAPTION).setValue("Tray"); item = type.addItem(Notification.Type.ASSISTIVE_NOTIFICATION); @@ -81,13 +87,12 @@ public class NotificationsWaiAria extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Generic test case for notifications"; } @Override protected Integer getTicketNumber() { - // TODO Auto-generated method stub return null; } @@ -97,13 +102,14 @@ public class NotificationsWaiAria extends TestBase { Type typeValue = (Type) type.getValue(); Notification n = new Notification(tf.getValue(), typeValue); + n.setDelayMsec(-1); n.setHtmlContentAllowed(true); NotificationConfiguration notificationConf = UI.getCurrent() .getNotificationConfiguration(); notificationConf.setAssistivePrefix(typeValue, prefix.getValue()); notificationConf.setAssistivePostfix(typeValue, postfix.getValue()); - notificationConf - .setAssistiveRole(typeValue, (NotificationRole) role.getValue()); + notificationConf.setAssistiveRole(typeValue, + (NotificationRole) role.getValue()); n.show(Page.getCurrent()); } @@ -118,4 +124,5 @@ public class NotificationsWaiAria extends TestBase { n.show(Page.getCurrent()); } } + } diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java new file mode 100644 index 0000000000..6b517e9887 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.notification; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.shared.ui.ui.NotificationRole; +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Unit test class for Notification ARIA (Accessible Rich Internet Applications) + * roles. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class NotificationsWaiAriaTest extends MultiBrowserTest { + + /** + * Checks if the ARIA roles are correctly applied to Notification. + * + * @since 7.2 + * @throws Exception + */ + @Test + public void notificationTest() throws Exception { + openTestURL(); + + TextFieldElement prefix = $(TextFieldElement.class).first(); + TextFieldElement postfix = $(TextFieldElement.class).get(1); + NativeSelectElement type = $(NativeSelectElement.class).first(); + ButtonElement show = $(ButtonElement.class).first(); + + prefix.clear(); + prefix.sendKeys("Prefix:"); + + postfix.clear(); + postfix.sendKeys("- press ESC to close"); + + type.selectByText(NotificationRole.ALERT.toString()); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + NotificationElement notification = $(NotificationElement.class).first(); + + String text = notification.getAttribute("role"); + Assert.assertTrue("Expected attribute 'role' to equal 'alert', found " + + text, text.equals("alert")); + + text = getHiddenText(notification.findElements( + By.className("v-assistive-device-only")).get(0)); + Assert.assertTrue("Expected 'Prefix:', found " + text, + text.equals("Prefix:")); + + text = getHiddenText(notification.findElements( + By.className("v-assistive-device-only")).get(1)); + Assert.assertTrue("Expected '- press ESC to close', found " + text, + text.equals("- press ESC to close")); + + try { + notification.closeNotification(); + } catch (Exception e) { + } + + type.selectByText("STATUS"); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + notification = $(NotificationElement.class).first(); + + text = notification.getAttribute("role"); + Assert.assertTrue("Expected attribute 'role' to equal 'status', found " + + text, text.equals("status")); + + try { + notification.closeNotification(); + } catch (Exception e) { + } + + prefix.clear(); + postfix.clear(); + + show.click(); + waitForElementPresent(By.className("v-Notification")); + + WebElement element; + try { + element = getDriver() + .findElement( + By.vaadin("Root/VNotification[0]/domChild[0]/domChild[0]/domChild[1]")); + } catch (Exception e) { + element = null; + } + Assert.assertNull( + "Notification shouldn't have assistive-device-only spans", + element); + + } + + private String getHiddenText(WebElement element) { + return (String) getTestBenchCommandExecutor().executeScript( + "return arguments[0].innerHTML", element); + } +} diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeak.java b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeak.java new file mode 100644 index 0000000000..b634e43f46 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeak.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.splitpanel; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.AbstractSplitPanel; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.HorizontalSplitPanel; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalSplitPanel; + +public class SplitPanelStyleLeak extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + CssLayout wrap = new CssLayout(); + addComponent(wrap); + + wrap.addComponent(getSplit(true, null)); + wrap.addComponent(getSplit(false, null)); + + wrap.addComponent(getSplit(true, "small")); + wrap.addComponent(getSplit(false, "small")); + + wrap.addComponent(getSplit(true, "large")); + wrap.addComponent(getSplit(false, "large")); + } + + private AbstractSplitPanel getSplit(boolean horizontal, String style) { + AbstractSplitPanel split = horizontal ? new HorizontalSplitPanel() + : new VerticalSplitPanel(); + + if (style != null) { + split.addStyleName(style); + } + split.setWidth("300px"); + split.setHeight("300px"); + + AbstractSplitPanel content = horizontal ? new VerticalSplitPanel() + : new HorizontalSplitPanel(); + content.addComponent(new Label("First")); + content.addComponent(new Label("Second")); + split.addComponent(content); + + content = horizontal ? new VerticalSplitPanel() + : new HorizontalSplitPanel(); + content.addComponent(new Label("First")); + split.addComponent(content); + + // Inception level nesting, but we need to test that the first level + // styles don't leak to a nested split panel with the same orientation + AbstractSplitPanel content2 = horizontal ? new HorizontalSplitPanel() + : new VerticalSplitPanel(); + content2.addComponent(new Label("First")); + content2.addComponent(new Label("Second")); + content.addComponent(content2); + + return split; + } + + @Override + protected String getTestDescription() { + return "Vertical/horizontal SplitPanel styles should not leak to any contained horizontal/vertical SplitPanel."; + } + + @Override + protected Integer getTicketNumber() { + return 14152; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeakTest.java b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeakTest.java new file mode 100644 index 0000000000..1ad9cdb461 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/splitpanel/SplitPanelStyleLeakTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.splitpanel; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class SplitPanelStyleLeakTest extends MultiBrowserTest { + + @Test + public void checkScreenshot() throws IOException { + openTestURL(); + compareScreen("all"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html deleted file mode 100644 index 6414c9bc03..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.html +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.EditableModeChange?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>24,8</td> -</tr> -<!--Set into editable mode--> -<tr> - <td>doubleClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>24,8</td> -</tr> -<!--Update name for selected row--> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>baa</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> - <td>34,11</td> -</tr> -<!--Ensure the name was updated--> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableEditableModeChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>baa</td> -</tr> -<!--Ensure the correct row is selected--> -<tr> - <td>screenCapture</td> - <td></td> - <td>selected-teemu</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java index fa8ab8f0f5..e792c90af1 100644 --- a/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java +++ b/uitest/src/com/vaadin/tests/components/table/EditableModeChange.java @@ -7,22 +7,24 @@ import java.util.Locale; import com.vaadin.data.Container; import com.vaadin.event.ItemClickEvent; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Component; import com.vaadin.ui.DefaultFieldFactory; import com.vaadin.ui.Field; import com.vaadin.ui.Table; import com.vaadin.ui.TableFieldFactory; -public class EditableModeChange extends TestBase { +public class EditableModeChange extends AbstractTestUI { private ItemClickEvent selectionEvent; private final String[] names = { "Teemu", "Teppo", "Seppo", "Matti", "Pekka" }; + @SuppressWarnings("unchecked") @Override - public void setup() { + public void setup(VaadinRequest request) { final Table items = new Table("Items - double-click to edit"); items.setSelectable(true); @@ -42,7 +44,7 @@ public class EditableModeChange extends TestBase { .setValue(new FormattedDate(cal.getTime().getTime())); } - items.addListener(new ItemClickEvent.ItemClickListener() { + items.addItemClickListener(new ItemClickEvent.ItemClickListener() { @Override public void itemClick(ItemClickEvent event) { @@ -89,7 +91,7 @@ public class EditableModeChange extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Double click a cell to edit, then click on another row to select it (editmode is set to false). The clicked row should now be selected without any flickering."; } diff --git a/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java b/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java new file mode 100644 index 0000000000..56b30dcb7c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/EditableModeChangeTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that editing and selecting work correctly. + * + * @author Vaadin Ltd + */ +public class EditableModeChangeTest extends MultiBrowserTest { + + @Test + public void testNotification() throws IOException, InterruptedException { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + + // check original value + TestBenchElement cell_1_0 = table.getCell(1, 0); + assertEquals( + "original value not found, wrong cell or contents (1st column of the 2nd row expected)", + "Teppo", cell_1_0.getText()); + + // double-click to edit cell contents + cell_1_0.click(); + new Actions(getDriver()).doubleClick(cell_1_0).build().perform(); + sleep(100); + + // fetch the updated cell + WebElement textField = table.getCell(1, 0).findElement( + By.className("v-textfield")); + assertEquals( + "original value not found, wrong cell or contents (1st column of the 2nd row expected)", + "Teppo", textField.getAttribute("value")); + + // update value + textField.clear(); + textField.sendKeys("baa"); + + // click on another row + table.getCell(0, 1).click(); + + // check the value got updated correctly + assertEquals( + "updated value not found, wrong cell or contents (1st column of the 2nd row expected)", + "baa", table.getCell(1, 0).getText()); + + // check that selection got updated correctly + List<WebElement> selected = table.findElement( + By.className("v-table-body")).findElements( + By.className("v-selected")); + assertEquals(1, selected.size()); + + WebElement content = selected.get(0).findElement( + By.className("v-table-cell-wrapper")); + assertEquals( + "expected value not found, wrong cell or contents (1st column of the 1st row expected)", + "Teemu", content.getText()); + + compareScreen("selection"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/LabelEmbeddedClickThroughForTable.html b/uitest/src/com/vaadin/tests/components/table/LabelEmbeddedClickThroughForTable.html index 62e3786a44..88ff0c01e7 100644 --- a/uitest/src/com/vaadin/tests/components/table/LabelEmbeddedClickThroughForTable.html +++ b/uitest/src/com/vaadin/tests/components/table/LabelEmbeddedClickThroughForTable.html @@ -55,7 +55,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>32,9</td> </tr> <!-- Moved here to avoid Opera issue #5588 --> @@ -71,7 +71,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> <td>22,6</td> </tr> <tr> @@ -86,7 +86,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[1]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[1]/domChild[0]</td> <td></td> </tr> <tr> @@ -96,7 +96,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> <td>22,6</td> </tr> <tr> @@ -106,7 +106,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VEmbedded[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VEmbedded[0]/domChild[0]</td> <td>19,14</td> </tr> <tr> @@ -116,7 +116,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VEmbedded[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableLabelEmbeddedClickThroughForTable::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VEmbedded[0]/domChild[0]</td> <td>16,15</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTable.java b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTable.java new file mode 100644 index 0000000000..1b76be3b72 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTable.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Table; + +/** + * Test UI Class for testing memory leak in table (#14159). + * + * @since + * @author Vaadin Ltd + */ +public class MemoryLeakTable extends AbstractTestUI { + Button btnAdd = new Button("Add rows"); + Button btnRemove = new Button("Remove rows"); + Button btnTenTimes = new Button("Do ten times"); + Table tbl = new Table(); + static final int COLS = 15; + static final int ROWS = 2000; + + private void addRows() { + IndexedContainer idx = new IndexedContainer(); + for (int i = 0; i < COLS; i++) { + idx.addContainerProperty("name " + i, String.class, "value"); + } + for (int i = 0; i < ROWS; i++) { + idx.addItem("item" + i); + } + tbl.setContainerDataSource(idx); + addComponent(tbl); + } + + private void removeRows() { + tbl.removeAllItems(); + removeComponent(tbl); + } + + @Override + protected void setup(VaadinRequest request) { + btnAdd.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + addRows(); + } + }); + btnRemove.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + removeRows(); + } + }); + addComponent(btnAdd); + addComponent(btnRemove); + } + + @Override + protected String getTestDescription() { + return "Generates table for memory leaking test"; + } + + @Override + protected Integer getTicketNumber() { + return 14159; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java new file mode 100644 index 0000000000..b4b8d93fbe --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import java.io.IOException; +import java.util.Random; + +import org.junit.Ignore; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.MultiBrowserTest.Browser; + +/** + * Test case creating and deleting table component in a loop, testing memory + * lead in Table component. This test should not be used in auto testing. + * + * To test memory consuption. Run test in debug mode. Take memory snapshot in + * Profiler in browser before and after the loop. Compare memory consuption. + * + * @since + * @author Vaadin Ltd + */ +@RunLocally(Browser.CHROME) +public class MemoryLeakTableTest extends MultiBrowserTest { + + /** + * + */ + private static final int ITERATIONS = 200; + + // To run locally in chrome download ChromeDriver for TB3 + // Set path to the chrome driver. In + // ./work/eclipse-run-selected-test.properties add line + // chrome.driver.path=path_to_driver + + // Test is marked as ignore to exclude it from auto testing + @Test + @Ignore + public void memoryTest() throws IOException { + // Set breakoint and look memory consuption in Profiler + // Mozilla Firefox doesn't provide memory usage profiler, use chrome. + + openTestURL(); + + ButtonElement btnAdd = $(ButtonElement.class).get(0); + + for (int i = 0; i < ITERATIONS; i++) { + btnAdd.click(); + ButtonElement btnDel = $(ButtonElement.class).get(1); + TableElement tbl = $(TableElement.class).get(0); + Random rand = new Random(); + int scrollValue = rand.nextInt(1500); + scrollTable(tbl, scrollValue); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + btnDel.click(); + } + // Set breakoint and look memory consuption in Profiler + btnAdd = $(ButtonElement.class).get(0); + } + + // Scrolls table element + // Method scroll in TalbeElement class has a bug + // + private void scrollTable(TableElement tbl, int value) { + WebElement actualElement = tbl.findElement(By + .className("v-table-body-wrapper")); + JavascriptExecutor js = tbl.getCommandExecutor(); + js.executeScript("arguments[0].scrollTop = " + value, actualElement); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/PropertyValueChange.html b/uitest/src/com/vaadin/tests/components/table/PropertyValueChange.html index 71d323cdc0..b5904120d6 100644 --- a/uitest/src/com/vaadin/tests/components/table/PropertyValueChange.html +++ b/uitest/src/com/vaadin/tests/components/table/PropertyValueChange.html @@ -28,7 +28,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VFilterSelect[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VFilterSelect[0]/domChild[1]</td> <td></td> </tr> <tr> @@ -48,7 +48,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> <tr> @@ -58,7 +58,7 @@ </tr> <tr> <td>type</td> - <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstablePropertyValueChange::PID_Seditortable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td>9</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/SetDataSourceWithPropertyIds.html b/uitest/src/com/vaadin/tests/components/table/SetDataSourceWithPropertyIds.html index 6975ef84d4..02132e45a7 100644 --- a/uitest/src/com/vaadin/tests/components/table/SetDataSourceWithPropertyIds.html +++ b/uitest/src/com/vaadin/tests/components/table/SetDataSourceWithPropertyIds.html @@ -23,7 +23,7 @@ </tr> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> <tr> @@ -38,7 +38,7 @@ </tr> <tr> <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> <tr> @@ -53,7 +53,7 @@ </tr> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> <tr> @@ -68,7 +68,7 @@ </tr> <tr> <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> <tr> @@ -83,7 +83,7 @@ </tr> <tr> <td>assertElementPresent</td> - <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSetDataSourceWithPropertyIds::PID_Stable/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td></td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java new file mode 100644 index 0000000000..e643ef5fa0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnly.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import java.io.Serializable; +import java.util.List; + +import com.vaadin.data.util.BeanContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @author Vaadin Ltd + */ + +@SuppressWarnings("serial") +public class SetPageFirstItemLoadsNeededRowsOnly extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final VerticalLayout layout = new VerticalLayout(); + addComponent(layout); + + final Label label = new Label(""); + addComponent(label); + + BeanContainer<String, Bean> beans = new BeanContainer<String, Bean>( + Bean.class) { + @Override + public List<String> getItemIds(int startIndex, int numberOfIds) { + label.setValue("rows requested: " + numberOfIds); + return super.getItemIds(startIndex, numberOfIds); + } + }; + + beans.setBeanIdProperty("i"); + for (int i = 0; i < 2000; i++) { + beans.addBean(new Bean(i)); + } + + final Table table = new Table("Beans", beans); + table.setVisibleColumns(new Object[] { "i" }); + layout.addComponent(table); + + table.setCurrentPageFirstItemIndex(table.size() - 1); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Only cached rows and rows in viewport should be rendered after " + + "calling table.setCurrentPageFirstItemIndex(n) - as opposed to all rows " + + "between the previous position and new position"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14135; + } + + public class Bean implements Serializable { + + private Integer i; + + public Bean(Integer i) { + this.i = i; + } + + public Integer getI() { + return i; + } + + public void setI(Integer i) { + this.i = i; + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.java b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.java new file mode 100644 index 0000000000..ebf53e9a6d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/SetPageFirstItemLoadsNeededRowsOnlyTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @author Vaadin Ltd + */ +public class SetPageFirstItemLoadsNeededRowsOnlyTest extends MultiBrowserTest { + + /* + * expectedRowsRequested is related to VScrollTable's cache_rate and + * pageLength. See for instance VScrollTable.ensureCacheFilled(). + * + * This also takes into account if the visible rows are at the very start or + * end of the table, if the user scrolled or the + * Table.setCurrentPageFirstItemIndex(int) method was used. + * + * This value should not change if cache_rate and pageLength are not changed + * as well, and if this test remains constant: the table is scrolled to the + * very end (done in the actual UI: SetPageFirstItemLoadsNeededRowsOnly). + */ + private int expectedRowsRequested = 45; + + @Test + public void verifyLoadedRows() throws InterruptedException { + + openTestURL(); + + // wait for events to be processed in UI after loading page + sleep(2000); + + String labelValue = $(LabelElement.class).get(1).getText(); + String expectedLabelValue = "rows requested: " + expectedRowsRequested; + String errorMessage = "Too many rows were requested"; + assertEquals(errorMessage, expectedLabelValue, labelValue); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/SortLabelsInTable.html b/uitest/src/com/vaadin/tests/components/table/SortLabelsInTable.html index 51f13af004..21d2d7f3b3 100644 --- a/uitest/src/com/vaadin/tests/components/table/SortLabelsInTable.html +++ b/uitest/src/com/vaadin/tests/components/table/SortLabelsInTable.html @@ -23,7 +23,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>Label 0</td> </tr> <tr> @@ -33,7 +33,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> <td>Label 14</td> </tr> <tr> @@ -58,22 +58,22 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>Label 0</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VLabel[0]</td> <td>Label 10</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[11]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[11]/VLabel[0]</td> <td>Label 19</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> <td>Label 4</td> </tr> <tr> @@ -98,17 +98,17 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>Label 9</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[8]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[8]/VLabel[0]</td> <td>Label 19</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> <td>Label 13</td> </tr> <tr> @@ -133,17 +133,17 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>Label 9</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[8]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[8]/VLabel[0]</td> <td>Label 19</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> <td>Label 13</td> </tr> <tr> @@ -168,22 +168,22 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VLabel[0]</td> <td>Label 0</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VLabel[0]</td> <td>Label 10</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[11]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[11]/VLabel[0]</td> <td>Label 19</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableSortLabelsInTable::/VVerticalLayout[0]/VVerticalLayout[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VLabel[0]</td> <td>Label 4</td> </tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html deleted file mode 100644 index 7ad0873c0f..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.html +++ /dev/null @@ -1,132 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TableClickAndDragOnIconAndComponents</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableClickAndDragOnIconAndComponents</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableClickAndDragOnIconAndComponents?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td> - <td>38,13</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td> - <td>1,1</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VLabel[0]</td> - <td>30,9</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>71,11</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VTextField[1]</td> - <td>34,9</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VEmbedded[0]/domChild[0]</td> - <td>9,8</td> -</tr> -<tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]</td> - <td>v-selected</td> -</tr> -<tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]</td> - <td>v-selected</td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[4]/domChild[1]</td> - <td>2,16</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[1]/domChild[0]</td> - <td>22,18</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableClickAndDragOnIconAndComponents::PID_Stestable-table/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[1]/domChild[0]</td> - <td>foo 4foo</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java index 62a131cbbf..64f1a64558 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java +++ b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponents.java @@ -9,29 +9,31 @@ import com.vaadin.event.dd.acceptcriteria.AcceptAll; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails; import com.vaadin.ui.Component; import com.vaadin.ui.Embedded; import com.vaadin.ui.Label; import com.vaadin.ui.Table; import com.vaadin.ui.Table.ColumnGenerator; +import com.vaadin.ui.Table.RowHeaderMode; import com.vaadin.ui.Table.TableDragMode; import com.vaadin.ui.TextField; -public class TableClickAndDragOnIconAndComponents extends TestBase { +public class TableClickAndDragOnIconAndComponents extends AbstractTestUI { private static final long serialVersionUID = -2534880024131980135L; private Table table; @Override - protected void setup() { + protected void setup(VaadinRequest request) { table = new Table(); table.addContainerProperty("foo", String.class, "foo"); table.addContainerProperty("red", String.class, "red"); table.addContainerProperty("icon", Resource.class, null); table.setSelectable(true); - table.setRowHeaderMode(Table.ROW_HEADER_MODE_ICON_ONLY); + table.setRowHeaderMode(RowHeaderMode.ICON_ONLY); table.setItemIconPropertyId("icon"); table.setId("testable-table"); addComponent(table); @@ -122,6 +124,7 @@ public class TableClickAndDragOnIconAndComponents extends TestBase { }); } + @SuppressWarnings("unchecked") private void addItemAfter(Object itemId, Object afterItemId) { Item item; if (afterItemId != null) { @@ -136,7 +139,7 @@ public class TableClickAndDragOnIconAndComponents extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Tests that you can click on a row icon in a table to select the row, or to drag the row. Verifies also that the table doesn't capture the click events meant for components inside the table"; } diff --git a/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java new file mode 100644 index 0000000000..4a46342cab --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableClickAndDragOnIconAndComponentsTest.java @@ -0,0 +1,238 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that clicking on active fields doesn't change Table selection, nor does + * dragging rows. + * + * @author Vaadin Ltd + */ +public class TableClickAndDragOnIconAndComponentsTest extends MultiBrowserTest { + @Test + public void testClickingAndDragging() { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + + // ensure there's no initial selection + List<WebElement> selected = table.findElements(By + .className("v-selected")); + assertTrue("selection found when there should be none", + selected.isEmpty()); + + // click a cell + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", table.getCell(1, 2).getText()); + table.getCell(1, 2).click(); + + // ensure the correct row and nothing but that got selected + selected = table.findElements(By.className("v-selected")); + assertFalse("no selection found when there should be some", + selected.isEmpty()); + // find cell contents (row header included) + List<WebElement> cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + assertEquals("unexpected table selection size", 1, selected.size()); + + List<WebElement> rows = table.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + assertEquals("unexpected table row count", 5, rows.size()); + + // find a row that isn't the one selected + cellContents = rows.get(2).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // click on a TextField on that row + WebElement textField = rows.get(2) + .findElements(By.className("v-textfield")).get(0); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", textField.getAttribute("value")); + textField.click(); + + // ensure the focus shifted correctly + List<WebElement> focused = table.findElements(By + .className("v-textfield-focus")); + assertEquals("unexpected amount of focused textfields", 1, + focused.size()); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", focused.get(0).getAttribute("value")); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + + // click on a Label on that row + WebElement label = rows.get(2).findElements(By.className("v-label")) + .get(0); + assertEquals( + "expected value not found, wrong cell or contents (5th column of the 3rd row expected)", + "foo 2foo", label.getText()); + label.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertTrue("focused textfields found when there should be none", + focused.isEmpty()); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // click on the selected row's textfield (same as earlier) + textField.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertEquals("unexpected amount of focused textfields", 1, + focused.size()); + assertEquals( + "expected value not found, wrong cell or contents (6th column of the 3rd row expected)", + "foo 2foo", focused.get(0).getAttribute("value")); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // find the readOnly TextField of the previously selected row + textField = rows.get(1).findElements(By.className("v-textfield")) + .get(1); + assertEquals( + "expected value not found, wrong cell or contents (7th column of the 2nd row expected)", + "foo 1foo", textField.getAttribute("value")); + assertEquals( + "expected readonly status not found, wrong cell or contents (7th column of the 2nd row expected)", + "true", textField.getAttribute("readonly")); + + // click on that TextField + textField.click(); + + // ensure the focus shifted correctly + focused = table.findElements(By.className("v-textfield-focus")); + assertTrue("focused textfields found when there should be none", + focused.isEmpty()); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 2nd row expected)", + "red 1foo", cellContents.get(2).getText()); + + // click the embedded icon of the other row + WebElement embedded = rows.get(2).findElement( + By.className("v-embedded")); + embedded.click(); + + // ensure the selection changed + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + + // check row you are about to drag + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 5th row expected)", + "red 4foo", cellContents.get(2).getText()); + + // check the row above it + cellContents = rows.get(3).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 4th row expected)", + "red 3foo", cellContents.get(2).getText()); + + // drag the row to the row that's two places above it (gets dropped + // below that) + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + new Actions(getDriver()).moveToElement(cellContents.get(2)) + .clickAndHold().moveToElement(rows.get(2)).release().perform(); + + // find the current order of the rows + rows = table.findElement(By.className("v-table-body")).findElements( + By.tagName("tr")); + assertEquals("unexpected table row count", 5, rows.size()); + + // ensure the row got dragged + cellContents = rows.get(3).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the dragged row expected, should be on 4th row now)", + "red 4foo", cellContents.get(2).getText()); + + cellContents = rows.get(4).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the previous 4th row expected, should be on 5th row now)", + "red 3foo", cellContents.get(2).getText()); + + // ensure the selection didn't change + selected = table.findElements(By.className("v-selected")); + assertEquals("unexpected table selection size", 1, selected.size()); + cellContents = selected.get(0).findElements( + By.className("v-table-cell-content")); + assertEquals( + "expected value not found, wrong cell or contents (3rd column of the 3rd row expected)", + "red 2foo", cellContents.get(2).getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html index a9a572e468..efb99410fe 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> <td></td> </tr> <!--Add icons to property 1,5,10--> diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html index 641d9480ca..d565fb5140 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnIcons-runo.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=runo</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=runo</td> <td></td> </tr> <!--Add icons to property 1,5,10--> diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidth.html b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidth.html index 9c8a12fe15..f2a3a06254 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidth.html +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidth.html @@ -23,7 +23,7 @@ </tr> <tr> <td>assertElementWidth</td> - <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td>80</td> </tr> <tr> @@ -33,7 +33,7 @@ </tr> <tr> <td>assertElementWidth</td> - <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td>120</td> </tr> <tr> @@ -43,7 +43,7 @@ </tr> <tr> <td>assertElementWidth</td> - <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td>80</td> </tr> <tr> @@ -53,7 +53,7 @@ </tr> <tr> <td>assertElementWidth</td> - <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableColumnResizeContentsWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> <td>100</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html index 8a83f27701..c382a7c766 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableGeneratedRows-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html deleted file mode 100644 index 4c2dec9784..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html +++ /dev/null @@ -1,418 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8888/" /> -<title>TableItemDescriptionGeneratorTest</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableItemDescriptionGeneratorTest</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/TableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<!--All on--> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Cell and row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>12,6</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Generated component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Row and Component tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VCheckBox[0]/domChild[0]</td> - <td>7,5</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementPositionLeft</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td>-5000</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUI.java index ec81194f14..809e639448 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUI.java @@ -5,7 +5,8 @@ import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.IndexedContainer; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; @@ -13,7 +14,7 @@ import com.vaadin.ui.Component; import com.vaadin.ui.Table; import com.vaadin.ui.TextField; -public class TableItemDescriptionGeneratorTest extends TestBase { +public class TableItemDescriptionGeneratorUI extends AbstractTestUI { private final String TEXT_PROPERTY_ID = "Text"; private final String GEN_WIDGET_PROPERTY_ID = "Generated component"; @@ -23,7 +24,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { private CheckBox tableRowItemDescription; @Override - protected void setup() { + protected void setup(VaadinRequest request) { final Table table = createTable(); table.setId("table"); componentDescription = new CheckBox("Tooltip on components"); @@ -73,7 +74,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { if (propertyId == null && tableRowItemDescription.getValue()) { return "Row description " + itemId; } else if (tableCellItemDescription.getValue()) { - return "Cell description " + itemId + "," + propertyId; + return "Cell description " + itemId + ", " + propertyId; } return null; } @@ -100,7 +101,7 @@ public class TableItemDescriptionGeneratorTest extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Cells and rows should have tooltips"; } @@ -109,13 +110,12 @@ public class TableItemDescriptionGeneratorTest extends TestBase { return 5414; } + @SuppressWarnings("unchecked") private Container createContainer(boolean description) { IndexedContainer container = new IndexedContainer(); container.addContainerProperty(TEXT_PROPERTY_ID, String.class, ""); container.addContainerProperty(WIDGET_PROPERTY_ID, Component.class, null); - // container.addContainerProperty(COLUMN3_PROPERTY_ID, String.class, - // ""); for (int i = 0; i < 5; i++) { Item item = container.addItem("item " + i); @@ -125,7 +125,6 @@ public class TableItemDescriptionGeneratorTest extends TestBase { b.setDescription("Button " + i + " description"); } item.getItemProperty(WIDGET_PROPERTY_ID).setValue(b); - // item.getItemProperty(COLUMN3_PROPERTY_ID).setValue("last" + i); } return container; diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java new file mode 100644 index 0000000000..555a38a91e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorUITest.java @@ -0,0 +1,241 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Tests Table tooltips with various settings. + * + * @author Vaadin Ltd + */ +public class TableItemDescriptionGeneratorUITest extends TooltipTest { + + @Test + public void testDescriptions() throws Exception { + openTestURL(); + + checkTooltipNotPresent(); + + TableElement table = $(TableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + // check text description + TestBenchElement cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Cell description item 1, Text"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + TestBenchElement cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Button 1 description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + TestBenchElement cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Textfield's own description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Cell description item 1, Text"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Cell description item 1, Component"); + + // move somewhere without a description + new Actions(getDriver()).moveToElement(checkboxes.get(2)).perform(); + sleep(1000); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Cell description item 1, Generated component"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Button 1 description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Textfield's own description"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = table.getCell(1, 0); + cell_1_0.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check button description + cell_1_1 = table.getCell(1, 1); + cell_1_1.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + + // check textfield's description + cell_1_2 = table.getCell(1, 2); + cell_1_2.showTooltip(); + checkTooltip("Row description item 1"); + + // move somewhere without a description + checkboxes.get(2).showTooltip(); + checkTooltipNotPresent(); + } + + @Test + public void testPosition() throws Exception { + openTestURL(); + + TableElement table = $(TableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + TestBenchElement cell_3_0 = table.getCell(3, 0); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_3_0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 3, Text"); + clearTooltip(); + + // move outside the cell + new Actions(getDriver()).moveToElement(checkboxes.get(2)).perform(); + + // move to the corner of the cell + new Actions(getDriver()).moveToElement(cell_3_0, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 3, Text"); + clearTooltip(); + + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + TestBenchElement cell_1_1 = table.getCell(1, 1); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_1_1).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Button 1 description"); + clearTooltip(); + + // move to the corner of the element, outside of the button + new Actions(getDriver()).moveToElement(cell_1_1, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Row description item 1"); + clearTooltip(); + + // check cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + TestBenchElement cell_4_2 = table.getCell(4, 2); + + // move to the center of the cell + new Actions(getDriver()).moveToElement(cell_4_2).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Textfield's own description"); + clearTooltip(); + + // move to the corner of the element, outside of the textfield + new Actions(getDriver()).moveToElement(cell_4_2, 0, 0).perform(); + sleep(1000); + + // ensure the tooltip is present + checkTooltip("Cell description item 4, Generated component"); + clearTooltip(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html b/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html index f13bd22e84..aa9bfd5391 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html +++ b/uitest/src/com/vaadin/tests/components/table/TableMultiSelectSimple-chameleon.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableMultiSelectSimple?restartApplication&theme=chameleon</td> + <td>/run/com.vaadin.tests.components.table.TableMultiSelectSimple?restartApplication&theme=chameleon</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html deleted file mode 100644 index a440ff84fb..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.html +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TableRowHeight2</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TableRowHeight2</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableRowHeight2</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowHeight2::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[1]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowHeight2::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[1]/VButton[1]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>1</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java index 0011fdca18..5c733b9e24 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java +++ b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2.java @@ -1,16 +1,19 @@ package com.vaadin.tests.components.table; +import com.vaadin.annotations.Theme; import com.vaadin.data.Item; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.themes.BaseTheme; -public class TableRowHeight2 extends TestBase { +@Theme("tests-tickets") +public class TableRowHeight2 extends AbstractTestUI { @Override - protected String getDescription() { + protected String getTestDescription() { return "The table contains 2 rows, which both should be shown completely as the table height is undefined."; } @@ -19,9 +22,9 @@ public class TableRowHeight2 extends TestBase { return 2747; } + @SuppressWarnings("unchecked") @Override - protected void setup() { - setTheme("tests-tickets"); + protected void setup(VaadinRequest request) { HorizontalLayout vl = new HorizontalLayout(); vl.setSizeFull(); diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.java b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.java new file mode 100644 index 0000000000..7074225311 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRowHeight2Test.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import java.io.IOException; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that rows are completely visible and clicking buttons doesn't change + * anything. + * + * @author Vaadin Ltd + */ +public class TableRowHeight2Test extends MultiBrowserTest { + + @Test + public void testRowHeights() throws IOException { + openTestURL(); + + compareScreen("initial"); + + TableElement table = $(TableElement.class).first(); + List<WebElement> rows = table.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + + rows.get(0).findElements(By.className("v-button")).get(1).click(); + rows.get(1).findElements(By.className("v-button")).get(1).click(); + + compareScreen("after"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html index e5b1f47f2d..5116fceb49 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html +++ b/uitest/src/com/vaadin/tests/components/table/TableRowScrolledBottom.html @@ -28,7 +28,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]</td> <td>This is a test item with long text so that there is something to see Nr. 100. This text must be long otherwise the timing issue on Firefox does not occur. This works fine in IE</td> </tr> <tr> @@ -43,7 +43,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableRowScrolledBottom::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[44]/VLabel[0]</td> <td>This is a test item with long text so that there is something to see Nr. 200. This text must be long otherwise the timing issue on Firefox does not occur. This works fine in IE</td> </tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java new file mode 100644 index 0000000000..d1d6edaa67 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRow.java @@ -0,0 +1,167 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +/** + * + * @author Vaadin Ltd + */ +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; + +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ + +/** + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class TableScrollAfterAddRow extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.UI#init(com.vaadin.server.VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + final int totalRows = 100; + + final VerticalLayout layout = new VerticalLayout(); + + final IndexedContainer datasource = new IndexedContainer(); + + datasource.addContainerProperty("value", Integer.class, -1); + for (int i = 0; i < totalRows; i++) { + addRow(datasource); + } + + final Table table = new Table(); + table.setContainerDataSource(datasource); + layout.addComponent(table); + addComponent(layout); + + final Label label = new Label(""); + layout.addComponent(label); + + NativeButton addRowButton = new NativeButton("Add row", + new NativeButton.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + addRow(datasource); + } + }); + + NativeButton jumpToLastRowButton = new NativeButton("Jump to last row", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToLastRow(table); + } + }); + NativeButton jumpTo15thRowButton = new NativeButton("Jump to 15th row", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToFifteenthRow(table); + } + }); + NativeButton jumpToFirstRowButton = new NativeButton( + "Jump to first row", new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + jumpToFirstRow(table); + } + }); + + NativeButton updateLabelButton = new NativeButton("UpdateLabel", + new NativeButton.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + label.setValue(Integer.toString(table + .getCurrentPageFirstItemIndex())); + } + }); + layout.addComponent(addRowButton); + layout.addComponent(jumpToLastRowButton); + layout.addComponent(jumpTo15thRowButton); + layout.addComponent(jumpToFirstRowButton); + layout.addComponent(updateLabelButton); + } + + private void jumpToFifteenthRow(Table table) { + table.setCurrentPageFirstItemIndex(14); + } + + private void jumpToLastRow(Table table) { + int visibleRows = table.getContainerDataSource().size(); + table.setCurrentPageFirstItemIndex(visibleRows - 1); + } + + private void jumpToFirstRow(Table table) { + table.setCurrentPageFirstItemIndex(0); + } + + private void addRow(IndexedContainer datasource) { + int rowNumber = datasource.size(); + Item row = datasource.addItem(rowNumber); + row.getItemProperty("value").setValue(rowNumber); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return ""; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14147; + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java new file mode 100644 index 0000000000..9242bae3d8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertEquals; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.commands.TestBenchCommandExecutor; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.screenshot.ImageComparison; +import com.vaadin.testbench.screenshot.ReferenceNameGenerator; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @author Vaadin Ltd + */ +public class TableScrollAfterAddRowTest extends MultiBrowserTest { + + @Before + public void init() { + openTestURL(); + } + + @Test + public void testJumpToFirstRow() throws InterruptedException { + jumpToFifteenthRow(); + jumpToFirstRow(); + assertEquals("0", getCurrentPageFirstItemIndex()); + } + + @Test + public void testAddRowAfterJumpToLastRow() throws InterruptedException { + jumpToLastRow(); + addRow(); + sleep(200); + assertEquals("85", getCurrentPageFirstItemIndex()); + } + + @Test + public void testAddRowAfterJumpingToLastRowAndScrollingUp() + throws InterruptedException { + jumpToLastRow(); + scrollUp(); + addRow(); + sleep(200); + Assert.assertNotEquals("86", getCurrentPageFirstItemIndex()); + } + + private void scrollUp() { + WebElement actualElement = getDriver().findElement( + By.className("v-table-body-wrapper")); + JavascriptExecutor js = new TestBenchCommandExecutor(getDriver(), + new ImageComparison(), new ReferenceNameGenerator()); + js.executeScript("arguments[0].scrollTop = " + 30, actualElement); + } + + private String getCurrentPageFirstItemIndex() throws InterruptedException { + ButtonElement updateLabelButton = $(ButtonElement.class).get(4); + LabelElement label = $(LabelElement.class).get(1); + updateLabelButton.click(); + sleep(200); + return label.getText(); + } + + private void addRow() { + ButtonElement button = $(ButtonElement.class).get(0); + button.click(); + } + + private void jumpToFirstRow() { + ButtonElement button = $(ButtonElement.class).get(3); + button.click(); + } + + private void jumpToFifteenthRow() { + ButtonElement button = $(ButtonElement.class).get(2); + button.click(); + } + + private void jumpToLastRow() { + ButtonElement button = $(ButtonElement.class).get(1); + button.click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html index 96df94148c..c6ccb4df73 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html +++ b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.html @@ -28,12 +28,12 @@ </tr> <tr> <td>assertValue</td> - <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#field</td> + <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#field</td> <td>5/24/13</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#popupButton</td> + <td>vaadin=runcomvaadintestscomponentstableTableSqlContainer::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VPopupCalendar[0]#popupButton</td> <td>9,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableTooManyColumns.java b/uitest/src/com/vaadin/tests/components/table/TableTooManyColumns.java new file mode 100644 index 0000000000..2d27636420 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableTooManyColumns.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.ColumnGenerator; + +public class TableTooManyColumns extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Table table = new Table(); + + table.setColumnCollapsingAllowed(true); + + for (int i = 0; i < 91; i++) { + table.addGeneratedColumn("COLUMN " + i, new ColumnGenerator() { + + @Override + public Object generateCell(Table source, Object itemId, + Object columnId) { + return columnId; + } + }); + } + + addComponent(table); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Table column drop down becomes too large to fit the screen."; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 14156; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableTooManyColumnsTest.java b/uitest/src/com/vaadin/tests/components/table/TableTooManyColumnsTest.java new file mode 100644 index 0000000000..2244365e00 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableTooManyColumnsTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.commands.TestBenchElementCommands; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TableTooManyColumnsTest extends MultiBrowserTest { + + @Test + public void testDropdownTable() throws IOException { + openTestURL(); + + WebElement element = findElement(By + .className("v-table-column-selector")); + + element.click(); + + WebElement menu = findElement(By.className("gwt-MenuBar-vertical")); + + TestBenchElementCommands scrollable = testBenchElement(menu); + scrollable.scroll(3000); + + compareScreen(getScreenshotBaseName()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableTooltips.html b/uitest/src/com/vaadin/tests/components/table/TableTooltips.html deleted file mode 100644 index 13ceea935f..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TableTooltips.html +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td> - <td>57,5</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 3,Text</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td> - <td>810,153</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>355,350</td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>822,249</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]</td> - <td>90,12</td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]</td> - <td>57,12</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td> - <td>1011,283</td> -</tr> -<tr> - <td>mouseMove</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[4]/VTextField[0]</td> - <td>58,10</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TableWithContainerRequiringEqualsForItemId.html b/uitest/src/com/vaadin/tests/components/table/TableWithContainerRequiringEqualsForItemId.html index 5364b1cd1e..0fb4648387 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableWithContainerRequiringEqualsForItemId.html +++ b/uitest/src/com/vaadin/tests/components/table/TableWithContainerRequiringEqualsForItemId.html @@ -23,7 +23,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> @@ -33,7 +33,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[14]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> @@ -58,7 +58,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> @@ -83,7 +83,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithContainerRequiringEqualsForItemId::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TabletContextMenu.java b/uitest/src/com/vaadin/tests/components/table/TabletContextMenu.java new file mode 100644 index 0000000000..193cb499a7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TabletContextMenu.java @@ -0,0 +1,139 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.event.ShortcutAction; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Table; + +/** + * A test UI for context menus on different parts of a VSCrollTable. + * + * This UI has no attached unit test due to the poor support of touch events on + * Selenium. + * + * @since + * @author Vaadin Ltd + */ +public class TabletContextMenu extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + setSizeFull(); + + HorizontalLayout layout = new HorizontalLayout(); + layout.setSizeFull(); + layout.setSpacing(true); + addComponent(layout); + + Table table1 = createTable("no scrolling, has context menu"); + addActionHandler(table1); + table1.addItem(); + layout.addComponent(table1); + + Table table2 = createTable("should scroll, has context menu"); + for (int i = 0; i < 100; ++i) { + table2.addItem(); + } + addActionHandler(table2); + layout.addComponent(table2); + + Table table3 = createTable("no scrolling, no context menu"); + table3.addItem(); + layout.addComponent(table3); + + Table table4 = createTable("should scroll, no context menu"); + for (int i = 0; i < 100; ++i) { + table4.addItem(); + } + layout.addComponent(table4); + } + + private Table createTable(String caption) { + Table table = new Table(caption); + table.setImmediate(true); + + table.addContainerProperty("column1", String.class, "test"); + table.setSizeFull(); + table.setHeight("500px"); + table.setSelectable(true); + + return table; + } + + private void addActionHandler(Table table) { + table.addActionHandler(new Handler() { + + Action tabNext = new ShortcutAction("Shift", + ShortcutAction.KeyCode.TAB, null); + Action tabPrev = new ShortcutAction("Shift+Tab", + ShortcutAction.KeyCode.TAB, + new int[] { ShortcutAction.ModifierKey.SHIFT }); + Action curDown = new ShortcutAction("Down", + ShortcutAction.KeyCode.ARROW_DOWN, null); + Action curUp = new ShortcutAction("Up", + ShortcutAction.KeyCode.ARROW_UP, null); + Action enter = new ShortcutAction("Enter", + ShortcutAction.KeyCode.ENTER, null); + Action add = new ShortcutAction("Add Below", + ShortcutAction.KeyCode.A, null); + Action delete = new ShortcutAction("Delete", + ShortcutAction.KeyCode.DELETE, null); + + @Override + public void handleAction(Action action, Object sender, Object target) { + System.out.println(action.getCaption()); + } + + @Override + public Action[] getActions(Object target, Object sender) { + return new Action[] { tabNext, tabPrev, curDown, curUp, enter, + add, delete }; + } + }); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Make sure empty table parts have context menu on touch screen devices"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 13694; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldRelativeWidth.html b/uitest/src/com/vaadin/tests/components/table/TextFieldRelativeWidth.html index 99f8f5bf9b..6e3d86175a 100644 --- a/uitest/src/com/vaadin/tests/components/table/TextFieldRelativeWidth.html +++ b/uitest/src/com/vaadin/tests/components/table/TextFieldRelativeWidth.html @@ -34,7 +34,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldRelativeWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTextFieldRelativeWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[2]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> @@ -44,7 +44,7 @@ </tr> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldRelativeWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[4]/VButton[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTextFieldRelativeWidth::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VScrollTable[0]/VScrollTable$FocusableScrollContextPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[4]/VButton[0]/domChild[0]/domChild[0]</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html deleted file mode 100644 index caaa15fa1c..0000000000 --- a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.html +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8888/" /> -<title>TextFieldValueGoesMissing</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TextFieldValueGoesMissing</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.table.TextFieldValueGoesMissing?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>73,10</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>test</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>contextmenu</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestscomponentstableTextFieldValueGoesMissing::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[2]/VScrollTable[0]/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[0]/VTextField[0]</td> - <td>test</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java index 9ffad7f1e4..89c9050361 100644 --- a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java +++ b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissing.java @@ -1,6 +1,7 @@ package com.vaadin.tests.components.table; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; @@ -8,17 +9,18 @@ import com.vaadin.ui.Table; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -public class TextFieldValueGoesMissing extends TestBase { +public class TextFieldValueGoesMissing extends AbstractTestUI { + @SuppressWarnings("unchecked") @Override - protected void setup() { + protected void setup(VaadinRequest request) { final VerticalLayout verticalLayout = new VerticalLayout(); final Label label1 = new Label("1"); final Label label2 = new Label("2"); Button button = new Button("Replace label"); - button.addListener(new Button.ClickListener() { + button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { @@ -45,7 +47,7 @@ public class TextFieldValueGoesMissing extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "Enter a text in the TextField in the table and press the 'Replace label' button. This replaces the label which is in the same layout as the table but should not cause the TextField in the table to lose its contents"; } diff --git a/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java new file mode 100644 index 0000000000..387882b6ca --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TextFieldValueGoesMissingTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that a text field's value isn't cleared after a label in the same + * layout is changed. + * + * @since 7.3 + * @author Vaadin Ltd + */ +public class TextFieldValueGoesMissingTest extends MultiBrowserTest { + + /* This test was rewritten from a TB2 test. */ + @Test + public void valueMissingTest() throws Exception { + openTestURL(); + + waitForElementVisible(By.className("v-textfield")); + + TextFieldElement textfield = $(TextFieldElement.class).first(); + textfield.focus(); + textfield.sendKeys("test"); + + $(ButtonElement.class).first().click(); + + new Actions(getDriver()).contextClick(textfield).perform(); + + Assert.assertEquals("test", textfield.getValue()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html deleted file mode 100644 index 825988173a..0000000000 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html +++ /dev/null @@ -1,241 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<title>TabKeyboardNavigation</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TabKeyboardNavigation</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/TabKeyboardNavigation?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>9,8</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>right</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 1</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>space</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 2</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>tab2</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td> - <td>right</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> - <td>right</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[3]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 2</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> - <td>space</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[3]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 5</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>skip-disabled-to-tab5</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>right</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[4]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 5</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>space</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[4]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 6</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[8]/domChild[0]/domChild[0]/domChild[0]</td> - <td>18,10</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[8]</td> - <td>right</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[9]</td> - <td>right</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[10]</td> - <td>right</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[8]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 9</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[10]</td> - <td>space</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[8]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 12</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>scrolled-right-to-tab-12</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[4]/domChild[0]/domChild[0]/domChild[0]</td> - <td>11,2</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[4]</td> - <td>left</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> - <td>left</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td> - <td>left</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td>1000</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 5</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td> - <td>space</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td>Tab 1</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>scrolled-left-to-tab-1</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.java index ba737f1df8..620f04fe60 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.java @@ -6,7 +6,8 @@ import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.util.Log; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; @@ -19,7 +20,16 @@ import com.vaadin.ui.TabSheet.Tab; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; -public class TabKeyboardNavigation extends TestBase { +/** + * Test if the click and key tab selection in a tabsheet generate the correct + * focus/blur events. + * + * The solution was broken in ticket (#14304) + * + * @since + * @author Vaadin Ltd + */ +public class TabKeyboardNavigation extends AbstractTestUI { int index = 1; ArrayList<Component> tabs = new ArrayList<Component>(); @@ -27,18 +37,18 @@ public class TabKeyboardNavigation extends TestBase { Log focusblur = new Log(10); @Override - protected void setup() { + protected void setup(VaadinRequest request) { ts.setWidth("500px"); ts.setHeight("500px"); - ts.addListener(new FocusListener() { + ts.addFocusListener(new FocusListener() { @Override public void focus(FocusEvent event) { focusblur.log("Tabsheet focused!"); } }); - ts.addListener(new BlurListener() { + ts.addBlurListener(new BlurListener() { @Override public void blur(BlurEvent event) { focusblur.log("Tabsheet blurred!"); @@ -74,7 +84,7 @@ public class TabKeyboardNavigation extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "The tab bar should be focusable and arrow keys should switch tabs. The del key should close a tab if closable."; } @@ -83,10 +93,18 @@ public class TabKeyboardNavigation extends TestBase { return 5100; } + public final static String LABEL_ID = "sheetLabel"; + + public final static String labelID(int index) { + return LABEL_ID + index; + } + private Tab addTab() { Layout content = new VerticalLayout(); tabs.add(content); - content.addComponent(new Label("Tab " + index)); + Label label = new Label("Tab " + index); + label.setId(labelID(index)); + content.addComponent(label); content.addComponent(new TextField()); Tab tab = ts.addTab(content, "Tab " + index, null); if (index == 2) { diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationTest.java new file mode 100644 index 0000000000..65307f9492 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationTest.java @@ -0,0 +1,188 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.tabsheet; + +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Add TB3 test as the TB2 one failed on keyboard events. + * + * @since + * @author Vaadin Ltd + */ +public class TabKeyboardNavigationTest extends MultiBrowserTest { + + @Test + public void testFocus() throws InterruptedException, IOException { + openTestURL(); + + click(1); + sendKeys(1, Keys.ARROW_RIGHT); + + assertSheet(1); + sendKeys(2, Keys.SPACE); + assertSheet(2); + compareScreen("tab2"); + + sendKeys(2, Keys.ARROW_RIGHT); + sendKeys(3, Keys.ARROW_RIGHT); + assertSheet(2); + + sendKeys(5, Keys.SPACE); + assertSheet(5); + compareScreen("skip-disabled-to-tab5"); + + TestBenchElement addTabButton = (TestBenchElement) getDriver() + .findElements(By.className("v-button")).get(0); + + click(addTabButton); + + click(5); + sendKeys(5, Keys.ARROW_RIGHT); + assertSheet(5); + + sendKeys(6, Keys.SPACE); + assertSheet(6); + + click(addTabButton); + click(addTabButton); + click(addTabButton); + click(addTabButton); + click(addTabButton); + click(addTabButton); + + click(8); + compareScreen("click-tab-8"); + + sendKeys(8, Keys.ARROW_RIGHT); + sendKeys(9, Keys.SPACE); + click(9); + compareScreen("tab-9"); + + sendKeys(9, Keys.ARROW_RIGHT); + Thread.sleep(DELAY); + + sendKeys(10, Keys.ARROW_RIGHT); + + // Here PhantomJS used to fail. Or when accessing tab2. The fix was to + // call the elem.click(x, y) using the (x, y) position instead of the + // elem.click() without any arguments. + sendKeys(11, Keys.ARROW_RIGHT); + + assertSheet(9); + sendKeys(12, Keys.SPACE); + assertSheet(12); + compareScreen("scrolled-right-to-tab-12"); + + click(5); + + sendKeys(5, Keys.ARROW_LEFT); + + // Here IE8 used to fail. A hidden <div> in IE8 would have the bounds of + // it's parent, and when trying to see in which direction to scroll + // (left or right) to make the key selected tab visible, the + // VTabSheet.scrollIntoView(Tab) used to check first whether the tab + // isClipped. On IE8 this will always return true for both hidden tabs + // on the left and clipped tabs on the right. So instead of going to + // left, it'll search all the way to the right. + sendKeys(3, Keys.ARROW_LEFT); + sendKeys(2, Keys.ARROW_LEFT); + assertSheet(5); + + sendKeys(1, Keys.SPACE); + assertSheet(1); + compareScreen("scrolled-left-to-tab-1"); + } + + /* + * Press key on the element. + */ + private void sendKeys(int tabIndex, Keys key) throws InterruptedException { + sendKeys(tab(tabIndex), key); + } + + /* + * Press key on the element. + */ + private void sendKeys(TestBenchElement element, Keys key) + throws InterruptedException { + + element.sendKeys(key); + if (DELAY > 0) { + sleep(DELAY); + } + } + + /* + * Click on the element. + */ + private void click(int tabIndex) throws InterruptedException { + click(tab(tabIndex)); + } + + /* + * Click on the element. + */ + private void click(TestBenchElement element) throws InterruptedException { + + element.click(10, 10); + if (DELAY > 0) { + sleep(DELAY); + } + } + + /* + * Delay for PhantomJS. + */ + private final static int DELAY = 10; + + private void assertSheet(int index) { + String labelCaption = "Tab " + index; + + By id = By.id(TabKeyboardNavigation.labelID(index)); + WebElement labelElement = getDriver().findElement(id); + + waitForElementPresent(id); + + Assert.assertEquals(labelCaption, labelCaption, labelElement.getText()); + } + + /* + * Provide the tab at specified index. + */ + private TestBenchElement tab(int index) { + By by = By.className("v-tabsheet-tabitemcell"); + + TestBenchElement element = (TestBenchElement) getDriver().findElements( + by).get(index - 1); + + String expected = "Tab " + index; + Assert.assertEquals(expected, + element.getText().substring(0, expected.length())); + + return element; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScroll.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScroll.java new file mode 100644 index 0000000000..3a5be51e47 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScroll.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Component; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.VerticalLayout; + +/** + * If the space is pressed on the tabs of a tabsheet the browser default scroll + * behavior must be prevented. + * + * @since + * @author Vaadin Ltd + */ +public class TabSpaceNotScroll extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + TabSheet tabSheet = new TabSheet(); + + for (int i = 0; i < 5; i++) { + String caption = "Tab " + i; + Component c = new Label(caption); + tabSheet.addTab(c, caption); + } + + addComponent(tabSheet); + + Label dontShowThis = new Label("Page scroll. This is bad."); + + VerticalLayout panel = new VerticalLayout(); + panel.setHeight("2000px"); + panel.addComponent(dontShowThis); + panel.setComponentAlignment(dontShowThis, Alignment.MIDDLE_CENTER); + + addComponent(panel); + } + + @Override + protected String getTestDescription() { + return "Pressing space on the tab should not scroll."; + } + + @Override + protected Integer getTicketNumber() { + return 14320; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScrollTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScrollTest.java new file mode 100644 index 0000000000..c35248c1f4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSpaceNotScrollTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.tabsheet; + +import java.io.IOException; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.Point; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test if the page scroll when press space on a tabsheet's tab. + * + * @since + * @author Vaadin Ltd + */ +public class TabSpaceNotScrollTest extends MultiBrowserTest { + + @Test + public void testScroll() throws InterruptedException, IOException { + openTestURL(); + + TestBenchElement tab = (TestBenchElement) getDriver().findElement( + By.className("v-tabsheet-tabitemcell")); + tab.click(10, 10); + + Point oldLocation = tab.getLocation(); + + tab.sendKeys(Keys.SPACE); + + Point newLocation = tab.getLocation(); + + Assert.assertEquals(oldLocation, newLocation); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpace.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpace.java new file mode 100644 index 0000000000..0105498f27 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpace.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TabSheet; + +/** + * Test to see if tabsheet navigation buttons render correctly in Chameleon + * + * @author Vaadin Ltd + */ +@Theme("chameleon") +public class TabsheetNotEnoughHorizontalSpace extends AbstractTestUI { + + private TabSheet tabsheet = new TabSheet(); + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + generateTabs(); + tabsheet.setSizeFull(); + addComponent(tabsheet); + + } + + private void generateTabs() { + tabsheet.removeAllComponents(); + for (int i = 0; i < 100; ++i) { + tabsheet.addTab(new Panel(), "Tab" + i); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Scroll-buttons should render correctly on all browsers"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 12154; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpaceTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpaceTest.java new file mode 100644 index 0000000000..990f545697 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetNotEnoughHorizontalSpaceTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.tabsheet; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that tabsheet's scroll button are rendered correctly in Chameleon + * theme. + * + * Ticket #12154 + * + * @since + * @author Vaadin Ltd + */ +public class TabsheetNotEnoughHorizontalSpaceTest extends MultiBrowserTest { + + @Test + public void testThatTabScrollButtonsAreRenderedCorrectly() + throws IOException { + openTestURL(); + + driver.findElement(By.className("v-tabsheet-scrollerPrev-disabled")); + driver.findElement(By.className("v-tabsheet-scrollerNext")); + + compareScreen(getScreenshotBaseName()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java new file mode 100644 index 0000000000..b2607050a4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResetted.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.textarea; + +import com.vaadin.event.UIEvents; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Component; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; + +/** + * Ticket #14080 + * + * - The bug happen on push event.<br/> + * - The changes in the DOM are css related.<br/> + * - It seems like when the class attribute is set on push, the textarea revert + * to the height defined by the rows attribute.<br/> + * - The size is reseted on onStateChange where the size is set to the one from + * the state. And it's because, when the user changes the text, at the next poll + * the state will confirm the change of the text, but the width and height + * didn't change in the state either client or server before the fix. + * + * @since + * @author Vaadin Ltd + */ +public class TextAreaSizeResetted extends AbstractTestUI { + + public static final int TEXTAREAHEIGHT = 200; + public static final int TEXTAREAWIDTH = 200; + + CssLayout layout = new CssLayout() { + @Override + protected String getCss(Component c) { + if (c instanceof TextArea) { + return "resize:both"; + } + + return super.getCss(c); + } + }; + + @Override + protected void setup(VaadinRequest request) { + setPollInterval(500); // Short polling like 100ms jams up the TestBench + // waitForVaadin -functionality. + + final Label pollIndicator = new Label(); + pollIndicator.setId("pollIndicator"); + + final TextField textField = new TextField("height"); + + final TextArea textArea = new TextArea(); + textArea.setHeight(TEXTAREAHEIGHT + "px"); + textArea.setWidth(TEXTAREAWIDTH + "px"); + textArea.setValue("This is a text."); + + Button button = new Button("Change Height", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + + textArea.setHeight(textField.getValue()); + } + }); + + addComponent(layout); + + layout.addComponent(textArea); + layout.addComponent(textField); + layout.addComponent(button); + layout.addComponent(pollIndicator); + + addPollListener(new UIEvents.PollListener() { + @Override + public void poll(UIEvents.PollEvent event) { + pollIndicator.setValue(String.valueOf(System + .currentTimeMillis())); + } + }); + } + + @Override + protected String getTestDescription() { + return "TextArea width/height change when user resize it, change the text then a poll come."; + } + + @Override + protected Integer getTicketNumber() { + return 14080; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java new file mode 100644 index 0000000000..6365d00735 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textarea/TextAreaSizeResettedTest.java @@ -0,0 +1,127 @@ +package com.vaadin.tests.components.textarea; + +import static com.vaadin.tests.components.textarea.TextAreaSizeResetted.TEXTAREAHEIGHT; +import static com.vaadin.tests.components.textarea.TextAreaSizeResetted.TEXTAREAWIDTH; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TextAreaElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TextAreaSizeResettedTest extends MultiBrowserTest { + + private final int OFFSET = 100; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + } + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return getBrowsersExcludingIE(); // IE8-11 don't support CSS resize. + } + + @Test + public void textAreaIsNotResizedOnBlur() { + + resizeAndAssertTextAreaTo(TEXTAREAHEIGHT, OFFSET); + + getTextArea().sendKeys("foo"); + + moveFocusOutsideTextArea(); + + // We can't use a waitUntil to check the text area size here, because it + // won't release the focus from + // the text area, so we need to do use something else. This workaround + // uses a label which is updated to indicate + // polling, which should trigger a resize. + waitUntilPollingOccurs(); + + assertThat(getTextAreaHeight(), is(TEXTAREAHEIGHT + OFFSET)); + assertThat(getTextAreaWidth(), is(TEXTAREAWIDTH + OFFSET)); + + waitUntilPollingOccurs(); + } + + private void moveFocusOutsideTextArea() { + $(TextFieldElement.class).first().focus(); + } + + private void resizeAndAssertTextAreaTo(int size, int offset) { + // Sanity check + assertThat(getTextAreaHeight(), is(size)); + resizeTextAreaBy(offset); + + assertThat(getTextAreaHeight(), is(size + offset)); + } + + private void resizeTextAreaBy(int offset) { + int resizeHandlerOffset = 10; + new Actions(getDriver()) + .moveToElement(getTextArea(), + TEXTAREAWIDTH - resizeHandlerOffset, + TEXTAREAHEIGHT - resizeHandlerOffset).clickAndHold() + .moveByOffset(offset, offset).release().build().perform(); + } + + @Test + public void textAreaWidthIsPresevedOnHeightResize() { + resizeAndAssertTextAreaTo(TEXTAREAHEIGHT, OFFSET); + + changeHeightTo(TEXTAREAHEIGHT + OFFSET + OFFSET); + + assertThat(getTextAreaWidth(), is(TEXTAREAWIDTH + OFFSET)); + assertThat(getTextAreaHeight(), is(TEXTAREAHEIGHT + OFFSET + OFFSET)); + } + + private void changeHeightTo(int offset) { + $(TextFieldElement.class).first().sendKeys(String.valueOf(offset)); + $(ButtonElement.class).first().click(); + } + + private void waitUntilPollingOccurs() { + final String timestamp = getPollTimestamp(); + + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return !timestamp.equals(getPollTimestamp()); + } + }); + } + + private String getPollTimestamp() { + return $(LabelElement.class).id("pollIndicator").getText(); + } + + private int getTextAreaHeight() { + return getTextAreaSize().getHeight(); + } + + private int getTextAreaWidth() { + return getTextAreaSize().getWidth(); + } + + private Dimension getTextAreaSize() { + return getTextArea().getSize(); + } + + private TextAreaElement getTextArea() { + return $(TextAreaElement.class).first(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html deleted file mode 100644 index 1a20b798ec..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.html +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>DisappearingComponents</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">DisappearingComponents</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.treetable.DisappearingComponents?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableDisappearingComponents::/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]</td> - <td>12,7</td> -</tr> -<tr> - <td>verifyElementPresent</td> - <td>vaadin=runcomvaadintestscomponentstreetableDisappearingComponents::/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VLink[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java index aaa7496616..ee64007234 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java +++ b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponents.java @@ -1,16 +1,15 @@ package com.vaadin.tests.components.treetable; import com.vaadin.server.ExternalResource; -import com.vaadin.tests.components.AbstractTestCase; -import com.vaadin.ui.LegacyWindow; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Link; import com.vaadin.ui.TreeTable; -public class DisappearingComponents extends AbstractTestCase { +public class DisappearingComponents extends AbstractTestUI { @Override - public void init() { - LegacyWindow mainWindow = new LegacyWindow("Application"); + public void setup(VaadinRequest request) { final TreeTable tt = new TreeTable(); tt.setSizeUndefined(); tt.setWidth("100%"); @@ -33,13 +32,11 @@ public class DisappearingComponents extends AbstractTestCase { tt.setChildrenAllowed(items[2], false); tt.setParent(items[2], items[1]); - mainWindow.addComponent(tt); - - setMainWindow(mainWindow); + addComponent(tt); } @Override - protected String getDescription() { + protected String getTestDescription() { return "TreeTable column component empty after expand+collapse when pageLength is set to zero"; } diff --git a/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java new file mode 100644 index 0000000000..e4d97b9de1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/DisappearingComponentsTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.treetable; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.TreeTableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that expanded cells with component contents aren't empty. + * + * @author Vaadin Ltd + */ +public class DisappearingComponentsTest extends MultiBrowserTest { + + @Test + public void testNotification() throws InterruptedException { + openTestURL(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + treeTable.getCell(1, 0) + .findElement(By.className("v-treetable-treespacer")).click(); + sleep(100); + + WebElement link = treeTable.getCell(2, 1).findElement( + By.className("v-link")); + assertEquals("3", link.getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableGeneratedColumns.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableGeneratedColumns.html index 09014f3aa0..52d2fd7b3f 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableGeneratedColumns.html +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableGeneratedColumns.html @@ -60,7 +60,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VLabel[0]</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/VScrollTable$FocusableScrollContextPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VLabel[0]</td> <td>Item 1/Generated 1</td> </tr> <!--100px html label--> @@ -86,7 +86,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VLabel[1]</td> + <td>vaadin=runcomvaadintestscomponentstreetableTreeTableTest::PID_StestComponent/VScrollTable$FocusableScrollContextPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VLabel[1]</td> <td>Item 1/Generated 2</td> </tr> <!--plain string--> diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html deleted file mode 100644 index 7f2f61bfc3..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.html +++ /dev/null @@ -1,357 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:8888/" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/TreeTableItemDescriptionGeneratorTest?restartApplication</td> - <td></td> -</tr> -<!--All on--> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Cell and row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>12,6</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Text</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Cell description item 1,Generated component</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Row and Component tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VCheckBox[0]/domChild[0]</td> - <td>7,5</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Button 1 description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Textfield's own description</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Row tooltips--> -<tr> - <td>mouseClick</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VCheckBox[0]/domChild[0]</td> - <td>7,8</td> -</tr> -<!--Text tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Button tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--TextField tooltip--> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VTextField[0]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>Row description item 1</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/domChild[3]</td> - <td>22,7</td> -</tr> -<tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTreeTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> - <td></td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUI.java index 2864156b03..ba057f4c41 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorTest.java +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUI.java @@ -15,14 +15,16 @@ */ package com.vaadin.tests.components.treetable; -import com.vaadin.tests.components.table.TableItemDescriptionGeneratorTest; +import com.vaadin.tests.components.table.TableItemDescriptionGeneratorUI; import com.vaadin.ui.Table; import com.vaadin.ui.TreeTable; -public class TreeTableItemDescriptionGeneratorTest extends - TableItemDescriptionGeneratorTest { +public class TreeTableItemDescriptionGeneratorUI extends + TableItemDescriptionGeneratorUI { + @Override protected Table createTable() { return new TreeTable(); } + } diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java new file mode 100644 index 0000000000..849d19cafa --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableItemDescriptionGeneratorUITest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.treetable; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.testbench.elements.TreeTableElement; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Tests TreeTable tooltips with various settings. + * + * @author Vaadin Ltd + */ +public class TreeTableItemDescriptionGeneratorUITest extends TooltipTest { + + @Test + public void testDescriptions() throws Exception { + openTestURL(); + + checkTooltipNotPresent(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + List<CheckBoxElement> checkboxes = $(CheckBoxElement.class).all(); + assertEquals(3, checkboxes.size()); + + // check text description + TestBenchElement cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Cell description item 1, Text"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + TestBenchElement cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Button 1 description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + TestBenchElement cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Textfield's own description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Cell description item 1, Text"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Cell description item 1, Component"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Cell description item 1, Generated component"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + // uncheck cell tooltips + checkboxes.get(1).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Button 1 description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Textfield's own description"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // uncheck component tooltips + checkboxes.get(0).findElement(By.tagName("input")).click(); + + // check text description + cell_1_0 = treeTable.getCell(1, 0); + checkTooltip(cell_1_0, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check button description + cell_1_1 = treeTable.getCell(1, 1); + checkTooltip(cell_1_1, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + + // check textfield's description + cell_1_2 = treeTable.getCell(1, 2); + checkTooltip(cell_1_2, "Row description item 1"); + + // move somewhere without a description + checkTooltip(checkboxes.get(2), null); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html deleted file mode 100644 index b8d6cdb22e..0000000000 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.html +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TreeTableOutOfSync</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TreeTableOutOfSync</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.treetable.TreeTableOutOfSync?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableOutOfSync::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>10,7</td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentstreetableTreeTableOutOfSync::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>verifyTextNotPresent</td> - <td>Something has caused us to be out of sync with the server.<br />Take note of any unsaved data, and click here to re-sync.</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java index 7f4aa7f671..b8a0ac61c2 100644 --- a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSync.java @@ -15,16 +15,18 @@ */ package com.vaadin.tests.components.treetable; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Notification; import com.vaadin.ui.Table; import com.vaadin.ui.TreeTable; -public class TreeTableOutOfSync extends TestBase { +public class TreeTableOutOfSync extends AbstractTestUI { @Override - protected void setup() { + protected void setup(VaadinRequest request) { TreeTable tt = new TreeTable(); tt.addContainerProperty("i", Integer.class, null); tt.addGeneratedColumn("text", new Table.ColumnGenerator() { @@ -35,10 +37,10 @@ public class TreeTableOutOfSync extends TestBase { Button button = new Button("text " + source.getContainerDataSource().getItem(itemId) .getItemProperty("i").getValue()); - button.addListener(new Button.ClickListener() { + button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { - getMainWindow().showNotification("click"); + Notification.show("click"); } }); return button; @@ -56,7 +58,7 @@ public class TreeTableOutOfSync extends TestBase { } @Override - protected String getDescription() { + protected String getTestDescription() { return "When a root node is expanded, components created by a column generator go out of sync"; } diff --git a/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.java b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.java new file mode 100644 index 0000000000..0831232df7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/treetable/TreeTableOutOfSyncTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.treetable; + +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.TreeTableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that opening the root node and clicking a generated component doesn't + * cause out of sync (or any other system notifications). + * + * @author Vaadin Ltd + */ +public class TreeTableOutOfSyncTest extends MultiBrowserTest { + + @Test + public void testNotification() throws InterruptedException { + openTestURL(); + + TreeTableElement treeTable = $(TreeTableElement.class).first(); + List<WebElement> rows = treeTable.findElement( + By.className("v-table-body")).findElements(By.tagName("tr")); + + WebElement treeSpacer = rows.get(0).findElement( + By.className("v-treetable-treespacer")); + treeSpacer.click(); + + sleep(100); + + rows = treeTable.findElement(By.className("v-table-body")) + .findElements(By.tagName("tr")); + WebElement button = rows.get(2).findElement(By.className("v-button")); + button.click(); + + List<WebElement> notifications = findElements(By + .className("v-Notification-system")); + assertTrue(notifications.isEmpty()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java new file mode 100644 index 0000000000..d4599fc1a3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemText.java @@ -0,0 +1,43 @@ +package com.vaadin.tests.components.ui; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; + +public class ComboboxSelectedItemText extends AbstractTestUIWithLog { + @Override + protected void setup(VaadinRequest request) { + getLayout() + .addComponent( + new Label( + "Select first ANTIGUA AND BARBUDA from the first combobox. Then select ANTIGUA AND BARBUDA from the second combobox. Finally, click the popup button on the first combobox. Before fix you would see UA AND BAR in the field.")); + + ComboBox combobox = new ComboBox("Text input enabled:"); + combobox.setWidth("100px"); + + combobox.addItem("AMERICAN SAMOA"); + combobox.addItem("ANTIGUA AND BARBUDA"); + + ComboBox combobox2 = new ComboBox("Text input disabled:"); + combobox2.setWidth("100px"); + combobox2.setTextInputAllowed(false); + + combobox2.addItem("AMERICAN SAMOA"); + combobox2.addItem("ANTIGUA AND BARBUDA"); + + getLayout().addComponent(combobox); + getLayout().addComponent(combobox2); + } + + @Override + protected String getTestDescription() { + return "Tests selected item is displayed from the beginning"; + } + + @Override + protected Integer getTicketNumber() { + return 13477; + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java new file mode 100644 index 0000000000..f826654022 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.ui; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test class for issue #13477, where selecting a combobox item that is too long + * would render the ending of an item instead of the beginning, which was + * considered less than informative. + * + * @author Vaadin Ltd + */ + +public class ComboboxSelectedItemTextTest extends MultiBrowserTest { + + public final String SCREENSHOT_NAME_EDITABLE = "LongComboboxItemSelectedEditable"; + public final String SCREENSHOT_NAME_NON_EDITABLE = "LongComboboxItemSelectedNonEditable"; + public final int INDEX_EDITABLE_COMBOBOX = 1; + public final int INDEX_NON_EDITABLE_COMBOBOX = 2; + + @Test + public void testCombobox() throws IOException { + testCombobox(INDEX_EDITABLE_COMBOBOX, INDEX_NON_EDITABLE_COMBOBOX, + SCREENSHOT_NAME_EDITABLE); + } + + @Test + public void testComboboxNonEditable() throws IOException { + testCombobox(INDEX_NON_EDITABLE_COMBOBOX, INDEX_EDITABLE_COMBOBOX, + SCREENSHOT_NAME_NON_EDITABLE); + } + + private void testCombobox(int indexToTest, int indexToFocus, + String screenshotIdentifier) throws IOException { + openTestURL(); + + WebElement comboBox = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToTest + "]/VFilterSelect[0]"); + WebElement comboBoxFocus = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToFocus + "]/VFilterSelect[0]"); + + // Select an element from the first (editable) combobox. + + comboBox.findElement(By.className("v-filterselect-button")).click(); + WebElement comboBoxPopup = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToTest + "]/VFilterSelect[0]#popup"); + comboBoxPopup.findElements(By.tagName("td")).get(2).click(); + + // Select an element from the second (non-editable combobox) to remove + // focus from the first combobox + + comboBoxFocus.findElement(By.className("v-filterselect-button")) + .click(); + comboBoxPopup = vaadinElement("/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[" + + indexToFocus + "]/VFilterSelect[0]#popup"); + comboBoxPopup.findElements(By.tagName("td")).get(2).click(); + + // click the popup on the first combobox. This would reveal the unwanted + // behaviour. + + comboBox.findElement(By.className("v-filterselect-button")).click(); + + // sadly, screenshot comparison is the only reasonable way to test a + // rendering issue. + + compareScreen(screenshotIdentifier); + + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/ui/UISerialization.html b/uitest/src/com/vaadin/tests/components/ui/UISerialization.html deleted file mode 100644 index 2379882a2c..0000000000 --- a/uitest/src/com/vaadin/tests/components/ui/UISerialization.html +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8888/" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.ui.UISerialization?restartApplication</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VLabel[0]</td> - <td>3. Diff states match, size: *</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VLabel[0]</td> - <td>2. Deserialized UI in *ms</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsuiUISerialization::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VVerticalLayout[0]/VOrderedLayout$Slot[2]/VLabel[0]</td> - <td>1. Serialized UI in *ms into * bytes</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/ui/UISerializationTest.java b/uitest/src/com/vaadin/tests/components/ui/UISerializationTest.java new file mode 100644 index 0000000000..cbe4dbdf29 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/UISerializationTest.java @@ -0,0 +1,26 @@ +package com.vaadin.tests.components.ui; + +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class UISerializationTest extends SingleBrowserTest { + @Test + public void tb2test() throws Exception { + openTestURL(); + $(ButtonElement.class).first().click(); + assertThat(getLogRow(0), startsWith("3. Diff states match, size: ")); + assertThat(getLogRow(1), startsWith("2. Deserialized UI in ")); + assertThat( + getLogRow(2), + allOf(startsWith("1. Serialized UI in"), + containsString(" into "), endsWith(" bytes"))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java index 1887427a72..ae966a5b07 100644 --- a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java +++ b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java @@ -109,7 +109,7 @@ public class TestFileUploadTest extends MultiBrowserTest { } private void setLocalFileDetector(WebElement element) throws Exception { - if (getClass().isAnnotationPresent(RunLocally.class)) { + if (getRunLocallyBrowser() != null) { return; } diff --git a/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java new file mode 100644 index 0000000000..2c5e415408 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUp.java @@ -0,0 +1,103 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.window; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Panel; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +/** + * Reproducing bug #12943 where an action on a Button or ComboBox placed at the + * bottom of a window in a scroll panel, will scroll up the parent panel. + * + * This was due to the fact that with the state confirmation notification from + * the server, the window.setVisible would be call again, and the hack that + * solved the scrollbars in a window (#11994) would cause the our bug. + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class BottomComponentScrollsUp extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Button b = new Button("Open window"); + addComponent(b); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + openWindow(); + } + + }); + + openWindow(); + } + + private void openWindow() { + Window w = new Window(); + w.setWidth("300px"); + w.setHeight("300px"); + w.center(); + + Panel p = createPanel(); + p.setSizeFull(); + + w.setContent(p); + + addWindow(w); + } + + private Panel createPanel() { + Panel p = new Panel(); + + VerticalLayout content = new VerticalLayout(); + p.setContent(content); + content.setHeight("500px"); + + List<String> items = new ArrayList<String>(); + items.add("1"); + items.add("2"); + items.add("3"); + + Button button = new Button("Press me"); + content.addComponent(button); + content.setComponentAlignment(button, Alignment.BOTTOM_CENTER); + return p; + } + + @Override + protected String getTestDescription() { + return "Interacting with a component at the bottom of scrollable panel within a subwindow scrolls up"; + } + + @Override + protected Integer getTicketNumber() { + return 12943; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.java b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.java new file mode 100644 index 0000000000..3d0da2677b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/BottomComponentScrollsUpTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.window; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Automatic test for fix for #12943. + * + * While testing without the fix, the test failed on both Chrome and PhantomJS. + * + * @since + * @author Vaadin Ltd + */ +public class BottomComponentScrollsUpTest extends MultiBrowserTest { + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + } + + @Test + public void windowScrollTest() throws IOException, InterruptedException { + TestBenchElement panelScrollable = (TestBenchElement) getDriver() + .findElement(By.className("v-panel-content")); + Dimension panelScrollableSize = panelScrollable.getSize(); + + WebElement verticalLayout = panelScrollable.findElement(By + .className("v-verticallayout")); + Dimension verticalLayoutSize = verticalLayout.getSize(); + + panelScrollable.scroll(verticalLayoutSize.height); + + WebElement button = verticalLayout + .findElement(By.className("v-button")); + + button.click(); + + // Loose the focus from the button. + new Actions(getDriver()) + .moveToElement(panelScrollable, panelScrollableSize.width / 2, + panelScrollableSize.height / 2).click().build() + .perform(); + + compareScreen("window"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java b/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java index e65a24e907..627efdc5b3 100644 --- a/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java +++ b/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java @@ -35,8 +35,6 @@ public class ComboboxScrollableWindowTest extends MultiBrowserTest { @Test public void testWindowScrollbars() throws Exception { openTestURL(); - com.vaadin.testbench.Parameters - .setScreenshotComparisonCursorDetection(true); WebElement window = driver.findElement(By.id(WINDOW_ID)); WebElement scrollableElement = window.findElement(By diff --git a/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.html b/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.html deleted file mode 100644 index f926696d63..0000000000 --- a/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.html +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TestTooSmallSubwindowSize</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TestTooSmallSubwindowSize</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.window.TestTooSmallSubwindowSize</td> - <td></td> -</tr> -<tr> - <td>waitForVaadin</td> - <td></td> - <td></td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.java b/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.java index 46845748a3..669774f715 100644 --- a/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.java +++ b/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSize.java @@ -1,15 +1,22 @@ package com.vaadin.tests.components.window; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; -public class TestTooSmallSubwindowSize extends TestBase { +/** + * Tests that the styles work correctly in tiny subwindows that have more + * content than can fit. + * + * @author Vaadin Ltd + */ +public class TestTooSmallSubwindowSize extends AbstractTestUI { @Override - protected String getDescription() { - return "The size of the subwindow (outer size) is set to 60x60 pixels. Minimum size for the content area is 150x100, which means the window and shadow should be around 155x155 and the content area 150x100. The decoration at the lower left corner of the window must not be missing either."; + protected String getTestDescription() { + return "The size of the subwindows (outer size) is set to 60x60 pixels. Make sure the shadows fits the windows instead of the contents. The decorations at the lower right corners of the resizable windows must not be missing either."; } @Override @@ -18,7 +25,14 @@ public class TestTooSmallSubwindowSize extends TestBase { } @Override - protected void setup() { + protected void setup(VaadinRequest request) { + getUI().addWindow(createNonResizableWindow()); + getUI().addWindow(createNonResizableWindowWithHorizontalScrollbar()); + getUI().addWindow(createResizableWindow()); + getUI().addWindow(createResizableWindowWithHorizontalScrollbar()); + } + + private Window createNonResizableWindow() { VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); Window w = new Window("Scroll", layout); @@ -35,13 +49,94 @@ public class TestTooSmallSubwindowSize extends TestBase { w.setPositionY(100); // Set window size - w.setWidth(60, Window.UNITS_PIXELS); - w.setHeight(60, Window.UNITS_PIXELS); + w.setWidth(60, Unit.PIXELS); + w.setHeight(60, Unit.PIXELS); + + // Disable resizing + w.setResizable(false); + + return w; + } + + private Window createNonResizableWindowWithHorizontalScrollbar() { + VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + Window w = new Window("Scroll", layout); + Label desc = new Label( + "This is a new child window with a preset" + + " width, height and position. Resizing has been" + + " disabled for this window. Additionally, this text label" + + " is intentionally too large to fit the window. You could" + + " use the scrollbars to view different parts of the window content," + + " except it's too small for that either."); + // disable wrapping + desc.setSizeUndefined(); + layout.addComponent(desc); + + // Set window position + w.setPositionX(200); + w.setPositionY(100); + + // Set window size + w.setWidth(60, Unit.PIXELS); + w.setHeight(60, Unit.PIXELS); // Disable resizing - w.setResizable(true); + w.setResizable(false); + + return w; + } + + private Window createResizableWindow() { + VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + Window w = new Window("Resize", layout); + Label desc = new Label( + "This is a new child window with a preset" + + " width, height and position. Resizing has not been" + + " disabled for this window. Additionally, this text label" + + " is intentionally too large to fit the window. You can resize or" + + " use the scrollbars to view different parts of the window content."); + layout.addComponent(desc); + + // Set window position + w.setPositionX(300); + w.setPositionY(100); + + // Set window size + w.setWidth(60, Unit.PIXELS); + w.setHeight(60, Unit.PIXELS); + + // Don't disable resizing + + return w; + } + + private Window createResizableWindowWithHorizontalScrollbar() { + VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + Window w = new Window("Resize", layout); + Label desc = new Label( + "This is a new child window with a preset" + + " width, height and position. Resizing has not been" + + " disabled for this window. Additionally, this text label" + + " is intentionally too large to fit the window. You can resize" + + " to view different parts of the window content."); + // disable wrapping + desc.setSizeUndefined(); + layout.addComponent(desc); + + // Set window position + w.setPositionX(400); + w.setPositionY(100); + + // Set window size + w.setWidth(60, Unit.PIXELS); + w.setHeight(60, Unit.PIXELS); + + // Don't disable resizing - getMainWindow().addWindow(w); + return w; } } diff --git a/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSizeTest.java b/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSizeTest.java new file mode 100644 index 0000000000..0019900884 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/TestTooSmallSubwindowSizeTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.components.window; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that the styles work correctly in tiny subwindows that have more + * content than can fit. + * + * @author Vaadin Ltd + */ +public class TestTooSmallSubwindowSizeTest extends MultiBrowserTest { + + @Test + public void testSubwindowStyles() throws IOException { + openTestURL(); + + compareScreen("initial"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java deleted file mode 100644 index 412fd3049d..0000000000 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * 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 - * - * http://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. - */ -package com.vaadin.tests.components.window; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.HasInputDevices; -import org.openqa.selenium.interactions.Mouse; -import org.openqa.selenium.interactions.internal.Coordinates; -import org.openqa.selenium.internal.Locatable; - -import com.vaadin.testbench.By; -import com.vaadin.tests.tb3.MultiBrowserTest; - -/** - * - * @since - * @author Vaadin Ltd - */ -public class TooltipInWindowTest extends MultiBrowserTest { - - @Test - public void testTooltipsInSubWindow() throws InterruptedException { - openTestURL(); - - WebElement textfield = vaadinElementById("tf1"); - Coordinates textfieldCoordinates = ((Locatable) textfield) - .getCoordinates(); - - Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); - - // Show tooltip - mouse.mouseMove(textfieldCoordinates, 10, 10); - - sleep(100); - ensureVisibleTooltipPositionedCorrectly(); - assertEquals("My tooltip", getTooltipElement().getText()); - - // Hide tooltip - mouse.mouseMove(textfieldCoordinates, -100, -100); - sleep(2000); - - ensureHiddenTooltipPositionedCorrectly(); - assertEquals("", getTooltipElement().getText()); - - // Show tooltip again - mouse.mouseMove(textfieldCoordinates, 10, 10); - - sleep(100); - ensureVisibleTooltipPositionedCorrectly(); - assertEquals("My tooltip", getTooltipElement().getText()); - - // Hide tooltip - mouse.mouseMove(textfieldCoordinates, -100, -100); - sleep(2000); - - ensureHiddenTooltipPositionedCorrectly(); - assertEquals("", getTooltipElement().getText()); - - } - - private WebElement getTooltipContainerElement() { - return getDriver().findElement(By.className("v-tooltip")); - } - - private void ensureVisibleTooltipPositionedCorrectly() { - WebElement textfield = vaadinElementById("tf1"); - int tooltipX = getTooltipContainerElement().getLocation().getX(); - int textfieldX = textfield.getLocation().getX(); - assertGreaterOrEqual("Tooltip should be positioned on the textfield (" - + tooltipX + " < " + textfieldX + ")", tooltipX, textfieldX); - } - - private void ensureHiddenTooltipPositionedCorrectly() { - int tooltipX = getTooltipContainerElement().getLocation().getX(); - assertLessThanOrEqual( - "Tooltip should be positioned outside of viewport (was at " - + tooltipX + ")", tooltipX, -1000); - } -} diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java index e067ada818..8d74e3a259 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java +++ b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java @@ -43,12 +43,13 @@ public class WindowMoveListenerTest extends MultiBrowserTest { waitUntilWindowHasReseted(window, winPos); } - private void waitUntilWindowHasReseted(final WebElement window, final Point winPos) { + private void waitUntilWindowHasReseted(final WebElement window, + final Point winPos) { waitUntil(new ExpectedCondition<Boolean>() { @Override public Boolean apply(WebDriver input) { - return winPos.x == window.getLocation().x && - winPos.y == window.getLocation().y; + return winPos.x == window.getLocation().x + && winPos.y == window.getLocation().y; } }, 5); } diff --git a/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdate.java b/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdate.java new file mode 100644 index 0000000000..4634ebff15 --- /dev/null +++ b/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdate.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ + +package com.vaadin.tests.extensions; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.Responsive; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; + +@Theme("tests-responsive") +public class ResponsiveLayoutUpdate extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + HorizontalLayout layout = new HorizontalLayout(); + layout.addStyleName("layout-update"); + layout.setWidth("100%"); + setContent(layout); + Responsive.makeResponsive(layout); + + Label label = new Label( + "This label changes its size between the breakpoints, allowing more space for the adjacent component."); + label.addStyleName("change-width"); + label.setSizeUndefined(); + layout.addComponent(label); + + Panel panel = new Panel("Panel"); + panel.setContent(new Label( + "This Panel should be maximized in both breakpoints.")); + panel.setSizeFull(); + layout.addComponent(panel); + layout.setExpandRatio(panel, 1); + } + + @Override + protected String getTestDescription() { + return "A new layout phase should be requested after a new breakpoint is triggered, ensuring any style changes affecting component sizes are taken into account."; + } + + @Override + protected Integer getTicketNumber() { + return 14354; + } +} diff --git a/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdateTest.java b/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdateTest.java new file mode 100644 index 0000000000..cd0a92d339 --- /dev/null +++ b/uitest/src/com/vaadin/tests/extensions/ResponsiveLayoutUpdateTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ + +package com.vaadin.tests.extensions; + +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.PanelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ResponsiveLayoutUpdateTest extends MultiBrowserTest { + + @Test + public void testWidthAndHeightRanges() throws Exception { + openTestURL(); + + final PanelElement panelElement = $(PanelElement.class).first(); + // I currently have no idea why PhantomJS wants a click here to work + // properly + panelElement.click(); + waitForElementVisible(By.cssSelector(".layout-update")); + + compareScreen("large"); + + // Resize below 600px width breakpoint + testBench().resizeViewPortTo(400, 768); + + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return panelElement.getSize().getWidth() < 500; + } + }); + compareScreen("small"); + } +} diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java index 52ea5f4f8e..ba3d0f06f1 100644 --- a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridLayoutWidthChangeTest.java @@ -17,7 +17,8 @@ public class GridLayoutWidthChangeTest extends MultiBrowserTest { compareScreen("initial"); - $(ButtonElement.class).caption("Reduce GridLayout parent width").first().click(); + $(ButtonElement.class).caption("Reduce GridLayout parent width") + .first().click(); compareScreen("buttonMoved"); } diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java new file mode 100644 index 0000000000..fc37455752 --- /dev/null +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumns.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.layouts.gridlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class GridSpanEmptyColumns extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + GridLayout gridLayout = new GridLayout(3, 1); + gridLayout.setWidth("1000px"); + + Label bigCell = new Label("big cell"); + bigCell.setId("bigCell"); + Label smallCell = new Label("small cell"); + smallCell.setId("smallCell"); + gridLayout.addComponent(bigCell, 0, 0, 1, 0); // spans first two columns + gridLayout.addComponent(smallCell, 2, 0, 2, 0); // last column only + + addComponent(gridLayout); + } + + @Override + protected String getTestDescription() { + return "A 3x1 grid has a spanned component on the first two cells and a component on the last cell. The two components should occupy 2/3 and 1/3 of the available space respectively, instead of 1/2 each."; + } + + @Override + protected Integer getTicketNumber() { + return 14335; + } +} diff --git a/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java new file mode 100644 index 0000000000..f2b86fb69b --- /dev/null +++ b/uitest/src/com/vaadin/tests/layouts/gridlayout/GridSpanEmptyColumnsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.layouts.gridlayout; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that GridLayout handles elements spanning otherwise empty columns + * correctly (#14335) + * + * @since 7.2.5 + * @author markus + */ +public class GridSpanEmptyColumnsTest extends MultiBrowserTest { + + @Test + public void componentsShouldMoveRight() throws IOException { + openTestURL(); + + LabelElement bigCell = $(LabelElement.class).id("bigCell"); + LabelElement smallCell = $(LabelElement.class).id("smallCell"); + + // Width is 1000px. Big cell should take up 2/3, small cell should take + // up 1/3. + assertEquals(667, bigCell.getSize().width); + assertEquals(333, smallCell.getSize().width); + + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java b/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java index 2771af01c6..84254b4935 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/GridLayout/GridAddReplaceMove.java @@ -36,7 +36,7 @@ public class GridAddReplaceMove extends GridBaseLayoutTestUI { /* * (non-Javadoc) - * + * * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. * VaadinRequest) */ diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java index 1c0e992a86..c4787045fc 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HAddReplaceMove.java @@ -19,7 +19,6 @@ import com.vaadin.annotations.Theme; import com.vaadin.tests.layouts.layouttester.BaseAddReplaceMove; import com.vaadin.ui.HorizontalLayout; - public class HAddReplaceMove extends BaseAddReplaceMove { /** diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java index bb974a8c68..3088a00c39 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/HLayout/HCaption.java @@ -19,7 +19,6 @@ import com.vaadin.annotations.Theme; import com.vaadin.tests.layouts.layouttester.BaseCaption; import com.vaadin.ui.HorizontalLayout; - public class HCaption extends BaseCaption { /** diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java index 57bb134be7..152e3f0b86 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutExpandTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutExpandTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java index e3e5914e3a..7f803781fb 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutRegErrorTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutRegErrorTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java index 372eb9cba4..519f8113f8 100644 --- a/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java +++ b/uitest/src/com/vaadin/tests/layouts/layouttester/VLayout/VLayoutSizingTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.layouts.layouttester.VLayout; import com.vaadin.tests.layouts.layouttester.BaseLayoutSizingTest; - /** * * @since diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java index 06ddc07abb..5dc15f8fc6 100644 --- a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java @@ -36,7 +36,7 @@ public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest { testBench(driver).disableWaitForVaadin(); // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java index f2207ccba7..a04d569e05 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java @@ -37,7 +37,8 @@ public class PushConfigurationLongPollingTest extends PushConfigurationTest { clearDebugMessages(); new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); - waitForDebugMessage("Push connection established using long-polling", 10); + waitForDebugMessage("Push connection established using long-polling", + 10); waitForServerCounterToUpdate(); } diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java index 00ee6bae25..e37bd32832 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java @@ -42,7 +42,7 @@ public class PushLargeDataLongPollingTest extends MultiBrowserTest { private void push() throws InterruptedException { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java index 26fa512ab2..058ac6cc92 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java @@ -42,7 +42,7 @@ public class PushLargeDataStreamingTest extends MultiBrowserTest { private void push() throws InterruptedException { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java index 57fb8c33b0..da4999799d 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java @@ -40,7 +40,7 @@ public class PushLargeDataWebsocketTest extends WebsocketTest { private void push() throws Exception { // Wait for startButton to be present - waitForElementToBePresent(vaadinLocatorById("startButton")); + waitForElementVisible(vaadinLocatorById("startButton")); String logRow0Id = "Log_row_0"; By logRow0 = vaadinLocatorById(logRow0Id); diff --git a/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java index 8a4593d70d..28ef30a04a 100644 --- a/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.push; - public class ReconnectLongPollingTest extends ReconnectTest { @Override diff --git a/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java index fe63764e78..0a0275c4d0 100755 --- a/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.push; - public class ReconnectStreamingTest extends ReconnectTest { @Override diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.java new file mode 100644 index 0000000000..4d02c4e62e --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnection.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.push; + +import com.vaadin.annotations.PreserveOnRefresh; +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; + +@Push +@PreserveOnRefresh +public class RefreshCloseConnection extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + log("Init"); + } + + @Override + protected void refresh(VaadinRequest request) { + if (getPushConnection().isConnected()) { + log("Still connected"); + } + log("Refresh"); + new Thread() { + @Override + public void run() { + accessSynchronously(new Runnable() { + @Override + public void run() { + log("Push"); + } + }); + } + }.start(); + } + + @Override + protected String getTestDescription() { + return "A log row should get pushed after reloading the page"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(14251); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java new file mode 100644 index 0000000000..c5c6064555 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.push; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.WebsocketTest; + +public class RefreshCloseConnectionTest extends MultiBrowserTest { + @Test + public void testSessionRefresh() { + openTestURL(); + + Assert.assertEquals("1. Init", getLogRow(0)); + + openTestURL(); + + Assert.assertEquals("2. Refresh", getLogRow(1)); + Assert.assertEquals("3. Push", getLogRow(0)); + } + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return WebsocketTest.getWebsocketBrowsers(); + } +} diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java index 1c18fb1912..333964e9bf 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java @@ -93,13 +93,13 @@ public class SerializerTest extends AbstractTestUI { rpc.sendInt(Integer.MAX_VALUE, Integer.valueOf(0), new int[] { 5, 7 }); state.intValue = Integer.MAX_VALUE; - state.intObjectValue = Integer.valueOf(0); + state.intObjectValue = Integer.valueOf(42); state.intArray = new int[] { 5, 7 }; rpc.sendLong(577431841358l, Long.valueOf(0), new long[] { -57841235865l, 57 }); - state.longValue = 577431841358l; - state.longObjectValue = Long.valueOf(0); + state.longValue = 577431841359l; + state.longObjectValue = Long.valueOf(577431841360l); state.longArray = new long[] { -57841235865l, 57 }; rpc.sendFloat(3.14159f, Float.valueOf(Math.nextUp(1)), new float[] { @@ -111,7 +111,7 @@ public class SerializerTest extends AbstractTestUI { rpc.sendDouble(Math.PI, Double.valueOf(-Math.E), new double[] { Double.MAX_VALUE, Double.MIN_VALUE }); state.doubleValue = Math.PI; - state.doubleValue = Double.valueOf(-Math.E); + state.doubleObjectValue = Double.valueOf(-Math.E); state.doubleArray = new double[] { Double.MAX_VALUE, Double.MIN_VALUE }; rpc.sendString("This is a tesing string ‡"); diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java index 5ca1e9ce6a..47bb212347 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java @@ -77,5 +77,36 @@ public class SerializerTestTest extends MultiBrowserTest { "sendBoolean: false, false, [false, false, true, false, true, true]", getLogRow(logRow++)); Assert.assertEquals("sendBeanSubclass: 43", getLogRow(logRow++)); + Assert.assertEquals( + "state.doubleArray: [1.7976931348623157e+308, 5e-324]", + getLogRow(logRow++)); + Assert.assertEquals("state.doubleObjectValue: -2.718281828459045", + getLogRow(logRow++)); + Assert.assertEquals("state.doubleValue: 3.141592653589793", + getLogRow(logRow++)); + Assert.assertEquals("state.floatArray: [57, 0, -12]", + getLogRow(logRow++)); + Assert.assertEquals("state.floatObjectValue: 1.0000001", + getLogRow(logRow++)); + Assert.assertEquals("state.floatValue: 3.14159", getLogRow(logRow++)); + Assert.assertEquals("state.longArray: [-57841235865, 57]", + getLogRow(logRow++)); + Assert.assertEquals("state.longObjectValue: 577431841360", + getLogRow(logRow++)); + Assert.assertEquals("state.longValue: 577431841359", + getLogRow(logRow++)); + Assert.assertEquals("state.intArray: [5, 7]", getLogRow(logRow++)); + Assert.assertEquals("state.intObjectValue: 42", getLogRow(logRow++)); + Assert.assertEquals("state.intValue: 2147483647", getLogRow(logRow++)); + Assert.assertEquals("state.charArray: aBcD", getLogRow(logRow++)); + Assert.assertEquals("state.charObjectValue: å", getLogRow(logRow++)); + Assert.assertEquals("state.charValue: ∫", getLogRow(logRow++)); + Assert.assertEquals("state.byteArray: [3, 1, 2]", getLogRow(logRow++)); + Assert.assertEquals("state.byteObjectValue: -12", getLogRow(logRow++)); + Assert.assertEquals("state.byteValue: 5", getLogRow(logRow++)); + Assert.assertEquals( + "state.booleanArray: [true, true, false, true, false, false]", + getLogRow(logRow++)); + } } diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index fa704d7b0b..b892fbe4a0 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -16,19 +16,36 @@ package com.vaadin.tests.tb3; +import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.Field; import java.net.URL; import java.util.Collections; import java.util.List; -import com.vaadin.testbench.TestBenchElement; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicHttpEntityEnclosingRequest; +import org.json.JSONException; +import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; -import org.openqa.selenium.*; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.Platform; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.HasInputDevices; import org.openqa.selenium.interactions.Keyboard; import org.openqa.selenium.interactions.Mouse; @@ -36,6 +53,7 @@ import org.openqa.selenium.interactions.internal.Coordinates; import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -45,13 +63,13 @@ import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; import com.vaadin.server.LegacyApplication; import com.vaadin.server.UIProvider; import com.vaadin.testbench.TestBench; +import com.vaadin.testbench.TestBenchDriverProxy; +import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.TestBenchTestCase; import com.vaadin.tests.components.AbstractTestUIWithLog; import com.vaadin.tests.tb3.MultiBrowserTest.Browser; import com.vaadin.ui.UI; -import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; - /** * Base class for TestBench 3+ tests. All TB3+ tests in the project should * extend this class. @@ -85,6 +103,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { */ private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000; + private static final int BROWSER_INIT_ATTEMPTS = 5; + private DesiredCapabilities desiredCapabilities; private boolean debug = false; @@ -95,6 +115,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { desiredCapabilities = Browser.FIREFOX.getDesiredCapabilities(); } + static { + com.vaadin.testbench.Parameters + .setScreenshotComparisonCursorDetection(true); + } + /** * Connect to the hub using a remote web driver, set the canvas size and * opens the initial URL as specified by {@link #getTestUrl()} @@ -120,9 +145,13 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { protected void setupDriver() throws Exception { DesiredCapabilities capabilities; - RunLocally runLocally = getClass().getAnnotation(RunLocally.class); - if (runLocally != null) { - capabilities = runLocally.value().getDesiredCapabilities(); + Browser runLocallyBrowser = getRunLocallyBrowser(); + if (runLocallyBrowser != null) { + if (System.getenv().containsKey("TEAMCITY_VERSION")) { + throw new RuntimeException( + "@RunLocally is not supported for tests run on the build server"); + } + capabilities = runLocallyBrowser.getDesiredCapabilities(); setupLocalDriver(capabilities); } else { capabilities = getDesiredCapabilities(); @@ -130,9 +159,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { if (localWebDriverIsUsed()) { setupLocalDriver(capabilities); } else { - WebDriver dr = TestBench.createDriver(new RemoteWebDriver( - new URL(getHubURL()), capabilities)); - setDriver(dr); + setupRemoteDriver(capabilities); } } @@ -152,8 +179,18 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } + protected Browser getRunLocallyBrowser() { + RunLocally runLocally = getClass().getAnnotation(RunLocally.class); + if (runLocally != null) { + return runLocally.value(); + } else { + return null; + } + } + protected WebElement getTooltipElement() { - return getDriver().findElement(com.vaadin.testbench.By.className("v-tooltip-text")); + return getDriver().findElement( + com.vaadin.testbench.By.className("v-tooltip-text")); } protected Coordinates getCoordinates(TestBenchElement element) { @@ -205,12 +242,63 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { DesiredCapabilities desiredCapabilities); /** + * Creates a {@link WebDriver} instance used for running the test remotely. + * + * @since + * @param capabilities + * the type of browser needed + * @throws Exception + */ + private void setupRemoteDriver(DesiredCapabilities capabilities) + throws Exception { + if (BrowserUtil.isIE(capabilities)) { + capabilities.setCapability( + InternetExplorerDriver.REQUIRE_WINDOW_FOCUS, + requireWindowFocusForIE()); + capabilities.setCapability( + InternetExplorerDriver.ENABLE_PERSISTENT_HOVERING, + usePersistentHoverForIE()); + } + + for (int i = 1; i <= BROWSER_INIT_ATTEMPTS; i++) { + try { + WebDriver dr = TestBench.createDriver(new RemoteWebDriver( + new URL(getHubURL()), capabilities)); + setDriver(dr); + return; + } catch (Exception e) { + System.err.println("Browser startup for " + capabilities + + " failed on attempt " + i + ": " + e.getMessage()); + if (i == BROWSER_INIT_ATTEMPTS) { + throw e; + } + } + } + + } + + /** * Opens the given test (defined by {@link #getTestUrl()}, optionally with * debug window and/or push (depending on {@link #isDebug()} and * {@link #isPush()}. */ protected void openTestURL() { - driver.get(getTestUrl()); + openTestURL(""); + } + + /** + * Opens the given test (defined by {@link #getTestUrl()}, optionally with + * debug window and/or push (depending on {@link #isDebug()} and + * {@link #isPush()}. + */ + protected void openTestURL(String extraParameters) { + String url = getTestUrl(); + if (url.contains("?")) { + url = url + "&" + extraParameters; + } else { + url = url + "?" + extraParameters; + } + driver.get(url); } /** @@ -328,8 +416,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @return Focused element or null */ protected WebElement getFocusedElement() { - Object focusedElement = ((JavascriptExecutor) getDriver()) - .executeScript("return document.activeElement"); + Object focusedElement = executeScript("return document.activeElement"); if (null != focusedElement) { return (WebElement) focusedElement; } else { @@ -338,6 +425,19 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** + * Executes the given Javascript + * + * @param script + * the script to execute + * @return whatever + * {@link org.openqa.selenium.JavascriptExecutor#executeScript(String, Object...)} + * returns + */ + protected Object executeScript(String script) { + return ((JavascriptExecutor) getDriver()).executeScript(script); + } + + /** * Find a Vaadin element based on its id given using Component.setId * * @param id @@ -383,7 +483,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become true */ - protected void waitUntil(ExpectedCondition<Boolean> condition) { + protected <T> void waitUntil(ExpectedCondition<T> condition) { waitUntil(condition, 10); } @@ -395,7 +495,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become true */ - protected void waitUntil(ExpectedCondition<Boolean> condition, + protected <T> void waitUntil(ExpectedCondition<T> condition, long timeoutInSeconds) { new WebDriverWait(driver, timeoutInSeconds).until(condition); } @@ -408,7 +508,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become false */ - protected void waitUntilNot(ExpectedCondition<Boolean> condition) { + protected <T> void waitUntilNot(ExpectedCondition<T> condition) { waitUntilNot(condition, 10); } @@ -420,14 +520,42 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @param condition * the condition to wait for to become false */ - protected void waitUntilNot(ExpectedCondition<Boolean> condition, + protected <T> void waitUntilNot(ExpectedCondition<T> condition, long timeoutInSeconds) { waitUntil(ExpectedConditions.not(condition), timeoutInSeconds); } - protected void waitForElementToBePresent(By by) { - waitUntil(ExpectedConditions.not(ExpectedConditions - .invisibilityOfElementLocated(by))); + protected void waitForElementPresent(final By by) { + waitUntil(ExpectedConditions.presenceOfElementLocated(by)); + } + + protected void waitForElementVisible(final By by) { + waitUntil(ExpectedConditions.visibilityOfElementLocated(by)); + } + + /** + * Checks if the given element has the given class name. + * + * Matches only full class names, i.e. has ("foo") does not match + * class="foobar" + * + * @param element + * @param className + * @return + */ + protected boolean hasCssClass(WebElement element, String className) { + String classes = element.getAttribute("class"); + if (classes == null || classes.isEmpty()) { + return (className == null || className.isEmpty()); + } + + for (String cls : classes.split(" ")) { + if (className.equals(cls)) { + return true; + } + } + + return false; } /** @@ -804,6 +932,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { public static DesiredCapabilities ie(int version) { DesiredCapabilities c = DesiredCapabilities.internetExplorer(); c.setVersion("" + version); + c.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, + true); return c; } @@ -1025,4 +1155,93 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { return findElement(By.xpath("//button[@title='Debug message log']")); } + /** + * Should the "require window focus" be enabled for Internet Explorer. + * RequireWindowFocus makes tests more stable but seems to be broken with + * certain commands such as sendKeys. Therefore it is not enabled by default + * for all tests + * + * @return true, to use the "require window focus" feature, false otherwise + */ + protected boolean requireWindowFocusForIE() { + return false; + } + + /** + * Should the "enable persistent hover" be enabled for Internet Explorer. + * + * Persistent hovering causes continuous firing of mouse over events at the + * last location the mouse cursor has been moved to. This is to avoid + * problems where the real mouse cursor is inside the browser window and + * Internet Explorer uses that location for some undefined operation + * (http:// + * jimevansmusic.blogspot.fi/2012/06/whats-wrong-with-internet-explorer + * .html) + * + * @return true, to use the "persistent hover" feature, false otherwise + */ + protected boolean usePersistentHoverForIE() { + return true; + } + + // FIXME: Remove this once TB4 getRemoteControlName works properly + private RemoteWebDriver getRemoteDriver() { + WebDriver d = getDriver(); + if (d instanceof TestBenchDriverProxy) { + try { + Field f = TestBenchDriverProxy.class + .getDeclaredField("actualDriver"); + f.setAccessible(true); + return (RemoteWebDriver) f.get(d); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (d instanceof RemoteWebDriver) { + return (RemoteWebDriver) d; + } + + return null; + + } + + // FIXME: Remove this once TB4 getRemoteControlName works properly + protected String getRemoteControlName() { + try { + RemoteWebDriver d = getRemoteDriver(); + if (d == null) { + return null; + } + HttpCommandExecutor ce = (HttpCommandExecutor) d + .getCommandExecutor(); + String hostName = ce.getAddressOfRemoteServer().getHost(); + int port = ce.getAddressOfRemoteServer().getPort(); + HttpHost host = new HttpHost(hostName, port); + DefaultHttpClient client = new DefaultHttpClient(); + URL sessionURL = new URL("http://" + hostName + ":" + port + + "/grid/api/testsession?session=" + d.getSessionId()); + BasicHttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest( + "POST", sessionURL.toExternalForm()); + HttpResponse response = client.execute(host, r); + JSONObject object = extractObject(response); + URL myURL = new URL(object.getString("proxyId")); + if ((myURL.getHost() != null) && (myURL.getPort() != -1)) { + return myURL.getHost(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private static JSONObject extractObject(HttpResponse resp) + throws IOException, JSONException { + InputStream contents = resp.getEntity().getContent(); + StringWriter writer = new StringWriter(); + IOUtils.copy(contents, writer, "UTF8"); + JSONObject objToReturn = new JSONObject(writer.toString()); + return objToReturn; + } + } diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java index 305caf1cb5..ff824ad98a 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 Vaadind Ltd. - * + * * 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 - * + * * http://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 @@ -22,11 +22,13 @@ import java.io.IOException; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.util.Arrays; import java.util.Enumeration; import java.util.Properties; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.firefox.FirefoxBinary; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; @@ -34,23 +36,26 @@ import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.safari.SafariDriver; import com.vaadin.testbench.TestBench; +import com.vaadin.tests.tb3.MultiBrowserTest.Browser; /** * Provides values for parameters which depend on where the test is run. * Parameters should be configured in work/eclipse-run-selected-test.properties. * A template is available in uitest/. - * + * * @author Vaadin Ltd */ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { + private static final String RUN_LOCALLY_PROPERTY = "com.vaadin.testbench.runLocally"; private static final String HOSTNAME_PROPERTY = "com.vaadin.testbench.deployment.hostname"; private static final String PORT_PROPERTY = "com.vaadin.testbench.deployment.port"; private static final Properties properties = new Properties(); + private static final File propertiesFile = new File("work", + "eclipse-run-selected-test.properties"); static { - File file = new File("work", "eclipse-run-selected-test.properties"); - if (file.exists()) { + if (propertiesFile.exists()) { try { - properties.load(new FileInputStream(file)); + properties.load(new FileInputStream(propertiesFile)); } catch (IOException e) { throw new RuntimeException(e); } @@ -66,6 +71,16 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { return property; } + private static String getSource(String propertyName) { + if (properties.containsKey(propertyName)) { + return propertiesFile.getAbsolutePath(); + } else if (System.getProperty(propertyName) != null) { + return "System.getProperty()"; + } else { + return null; + } + } + @Override protected String getScreenshotDirectory() { String screenshotDirectory = getProperty("com.vaadin.testbench.screenshot.directory"); @@ -83,7 +98,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { @Override protected String getDeploymentHostname() { - if (getClass().getAnnotation(RunLocally.class) != null) { + if (getRunLocallyBrowser() != null) { return "localhost"; } return getConfiguredDeploymentHostname(); @@ -91,7 +106,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Gets the hostname that tests are configured to use. - * + * * @return the host name configuration value */ public static String getConfiguredDeploymentHostname() { @@ -111,7 +126,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Gets the port that tests are configured to use. - * + * * @return the port configuration value */ public static int getConfiguredDeploymentPort() { @@ -128,7 +143,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * Tries to automatically determine the IP address of the machine the test * is running on. - * + * * @return An IP address of one of the network interfaces in the machine. * @throws RuntimeException * if there was an error or no IP was found @@ -165,7 +180,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /* * (non-Javadoc) - * + * * @see com.vaadin.tests.tb3.AbstractTB3Test#setupLocalDriver() */ @Override @@ -180,9 +195,28 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { driver = new FirefoxDriver(); } } else if (BrowserUtil.isChrome(desiredCapabilities)) { - System.setProperty("webdriver.chrome.driver", - getProperty("chrome.driver.path")); - driver = new ChromeDriver(); + String propertyName = "chrome.driver.path"; + String chromeDriverPath = getProperty(propertyName); + if (chromeDriverPath == null) { + throw new RuntimeException( + "You need to install ChromeDriver to use @" + + RunLocally.class.getSimpleName() + + " with Chrome." + + "\nFirst install it from https://code.google.com/p/selenium/wiki/ChromeDriver." + + "\nThen update " + + propertiesFile.getAbsolutePath() + + " to define a property named " + + propertyName + + " containing the path of your local ChromeDriver installation."); + } + System.setProperty("webdriver.chrome.driver", chromeDriverPath); + + // Tells chrome not to show warning + // "You are using an unsupported command-line flag: --ignore-certifcate-errors". + // #14319 + ChromeOptions options = new ChromeOptions(); + options.addArguments("--test-type "); + driver = new ChromeDriver(options); } else if (BrowserUtil.isSafari(desiredCapabilities)) { driver = new SafariDriver(); } else if (BrowserUtil.isPhantomJS(desiredCapabilities)) { @@ -196,4 +230,28 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { setDriver(TestBench.createDriver(driver)); setDesiredCapabilities(desiredCapabilities); } + + @Override + protected Browser getRunLocallyBrowser() { + Browser runLocallyBrowser = super.getRunLocallyBrowser(); + if (runLocallyBrowser != null) { + // Always use annotation value if present + return runLocallyBrowser; + } + + String runLocallyValue = getProperty(RUN_LOCALLY_PROPERTY); + if (runLocallyValue == null || runLocallyValue.trim().isEmpty()) { + return null; + } + + String browserName = runLocallyValue.trim().toUpperCase(); + try { + return Browser.valueOf(browserName); + } catch (IllegalArgumentException e) { + throw new RuntimeException("Invalid " + RUN_LOCALLY_PROPERTY + + " property from " + getSource(RUN_LOCALLY_PROPERTY) + + ": " + runLocallyValue + ". Expected one of " + + Arrays.toString(Browser.values())); + } + } } diff --git a/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java new file mode 100644 index 0000000000..f5dc337138 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.tb3; + +import java.util.Collections; +import java.util.List; + +import org.openqa.selenium.remote.DesiredCapabilities; + +public abstract class SingleBrowserTest extends PrivateTB3Configuration { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return Collections.unmodifiableList(Collections + .singletonList(MultiBrowserTest.Browser.PHANTOMJS + .getDesiredCapabilities())); + } + +} diff --git a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java index 4d29e479e2..0d540644bf 100644 --- a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java +++ b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java @@ -17,8 +17,10 @@ package com.vaadin.tests.tb3; import java.lang.annotation.Annotation; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; @@ -26,6 +28,8 @@ import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; import org.junit.Ignore; import org.junit.Test; import org.junit.runners.BlockJUnit4ClassRunner; @@ -34,10 +38,12 @@ import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.internal.HttpClientFactory; import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.tb3.AbstractTB3Test.BrowserUtil; -import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally; +import com.vaadin.tests.tb3.MultiBrowserTest.Browser; /** * This runner is loosely based on FactoryTestRunner by Ted Young @@ -50,6 +56,13 @@ import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally; public class TB3Runner extends BlockJUnit4ClassRunner { /** + * Socket timeout for HTTP connections to the grid hub. The connection is + * closed after 30 minutes of inactivity to avoid builds hanging for up to + * three hours per connection if the test client crashes/hangs. + */ + private static final int SOCKET_TIMEOUT = 30 * 60 * 1000; + + /** * This is the total limit of actual JUnit test instances run in parallel */ private static final int MAX_CONCURRENT_TESTS; @@ -67,12 +80,34 @@ public class TB3Runner extends BlockJUnit4ClassRunner { MAX_CONCURRENT_TESTS = 50; } service = Executors.newFixedThreadPool(MAX_CONCURRENT_TESTS); + + // reduce socket timeout to avoid tests hanging for three hours + try { + Field field = HttpCommandExecutor.class + .getDeclaredField("httpClientFactory"); + assert (Modifier.isStatic(field.getModifiers())); + field.setAccessible(true); + field.set(null, new HttpClientFactory() { + @Override + public HttpParams getHttpParams() { + HttpParams params = super.getHttpParams(); + // fifteen minute timeout + HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT); + return params; + } + }); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException( + "Changing socket timeout for TestBench failed", e); + } } protected static boolean localWebDriverIsUsed() { String useLocalWebDriver = System.getProperty("useLocalWebDriver"); - return useLocalWebDriver != null && useLocalWebDriver.toLowerCase().equals("true"); + return useLocalWebDriver != null + && useLocalWebDriver.toLowerCase().equals("true"); } public TB3Runner(Class<?> klass) throws InitializationError { @@ -185,17 +220,17 @@ public class TB3Runner extends BlockJUnit4ClassRunner { /* * Returns a list of desired browser capabilities according to browsers * defined in the test class, filtered by possible filter parameters. Use - * {@code @RunLocally} annotation to override all capabilities. + * {@code @RunLocally} annotation or com.vaadin.testbench.runLocally + * property to override all capabilities. */ private Collection<DesiredCapabilities> getDesiredCapabilities( AbstractTB3Test testClassInstance) { Collection<DesiredCapabilities> desiredCapabilites = getFilteredCapabilities(testClassInstance); - if (isRunLocally(testClassInstance)) { + Browser runLocallyBrowser = testClassInstance.getRunLocallyBrowser(); + if (runLocallyBrowser != null) { desiredCapabilites = new ArrayList<DesiredCapabilities>(); - desiredCapabilites.add(testClassInstance.getClass() - .getAnnotation(RunLocally.class).value() - .getDesiredCapabilities()); + desiredCapabilites.add(runLocallyBrowser.getDesiredCapabilities()); } return desiredCapabilites; @@ -237,10 +272,6 @@ public class TB3Runner extends BlockJUnit4ClassRunner { return filteredCapabilities; } - private boolean isRunLocally(AbstractTB3Test testClassInstance) { - return testClassInstance.getClass().getAnnotation(RunLocally.class) != null; - } - private AbstractTB3Test getTestClassInstance() throws InstantiationException, IllegalAccessException, InvocationTargetException { diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java new file mode 100644 index 0000000000..ec22edd205 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFly.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Image; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +@Theme("reindeer") +public class ThemeChangeOnTheFly extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + Button inject = new Button("Inject blue background"); + inject.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + getPage().getStyles().add( + ".v-app { background: blue !important;}"); + + } + }); + addComponent(inject); + + GridLayout gl = new GridLayout(2, 4); + gl.setCaption("Change theme by clicking a button"); + for (final String theme : new String[] { "reindeer", "runo", + "chameleon", "base", null }) { + Button b = new Button(theme); + b.setId(theme + ""); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + getUI().setTheme(theme); + } + }); + gl.addComponent(b); + } + + Table t = new Table(); + PersonContainer pc = PersonContainer.createWithTestData(); + pc.addNestedContainerBean("address"); + t.setContainerDataSource(pc); + gl.addComponent(t, 0, 3, 1, 3); + gl.setRowExpandRatio(3, 1); + + gl.setWidth("500px"); + gl.setHeight("800px"); + + HorizontalLayout images = new HorizontalLayout(); + images.setSpacing(true); + + Label l = new Label("Chameleon theme image in caption"); + l.setIcon(new ThemeResource("img/magnifier.png")); + images.addComponent(l); + Image image = new Image("Runo theme image", new ThemeResource( + "icons/64/ok.png")); + images.addComponent(image); + image = new Image("Reindeer theme image", new ThemeResource( + "button/img/left-focus.png")); + images.addComponent(image); + addComponent(images); + addComponent(gl); + + getLayout().setSpacing(true); + + Window w = new Window(); + w.setContent(new VerticalLayout(new Button("Button in window"))); + addWindow(w); + } + + @Override + protected String getTestDescription() { + return "Test that you can change theme on the fly"; + } + + @Override + protected Integer getTicketNumber() { + return 2874; + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java new file mode 100644 index 0000000000..eb010e82ee --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes; + +import java.io.IOException; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ThemeChangeOnTheFlyTest extends MultiBrowserTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // Seems like stylesheet onload is not fired on PhantomJS + // https://github.com/ariya/phantomjs/issues/12332 + List<DesiredCapabilities> l = super.getBrowsersToTest(); + l.remove(Browser.PHANTOMJS.getDesiredCapabilities()); + return l; + } + + @Test + public void injectedStyleAndThemeChange() throws IOException { + openTestURL(); + $(ButtonElement.class).caption("Inject blue background").first() + .click(); + changeTheme("runo"); + compareScreen("runo-blue-background"); + } + + @Test + public void reindeerToOthers() throws IOException { + openTestURL(); + compareScreen("reindeer"); + + changeThemeAndCompare("runo"); + changeThemeAndCompare("chameleon"); + changeThemeAndCompare("base"); + + } + + @Test + public void runoToReindeer() throws IOException { + openTestURL("theme=runo"); + compareScreen("runo"); + changeThemeAndCompare("reindeer"); + } + + @Test + public void reindeerToNullToReindeer() throws IOException { + openTestURL(); + + changeThemeAndCompare("null"); + changeThemeAndCompare("reindeer"); + } + + private void changeThemeAndCompare(String theme) throws IOException { + changeTheme(theme); + compareScreen(theme); + } + + private void changeTheme(String theme) { + $(ButtonElement.class).id(theme).click(); + if (theme.equals("null")) { + waitForThemeToChange(""); + assertOverlayTheme(""); + } else { + waitForThemeToChange(theme); + assertOverlayTheme(theme); + } + } + + private void waitForThemeToChange(final String theme) { + + final WebElement rootDiv = findElement(By + .xpath("//div[contains(@class,'v-app')]")); + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + String rootClass = rootDiv.getAttribute("class").trim(); + String expected = "v-app " + theme; + expected = expected.trim(); + return rootClass.equals(expected); + } + }, 30); + } + + private void assertOverlayTheme(String theme) { + final WebElement overlayContainerDiv = findElement(By + .xpath("//div[contains(@class,'v-overlay-container')]")); + String expected = "v-app v-overlay-container " + theme; + expected = expected.trim(); + + String overlayClass = overlayContainerDiv.getAttribute("class").trim(); + + Assert.assertEquals(expected, overlayClass); + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/Accordions.java b/uitest/src/com/vaadin/tests/themes/valo/Accordions.java index b401451271..c32be01d8d 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Accordions.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Accordions.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -44,6 +44,7 @@ public class Accordions extends VerticalLayout implements View { } Accordion getAccordion(String caption) { + TestIcon testIcon = new TestIcon(0); Accordion ac = new Accordion(); ac.setCaption(caption); ac.addTab(new VerticalLayout() { @@ -52,28 +53,28 @@ public class Accordions extends VerticalLayout implements View { addComponent(new Label( "Fabio vel iudice vincam, sunt in culpa qui officia. Ut enim ad minim veniam, quis nostrud exercitation.")); } - }, "First Caption", TestIcon.get()); + }, "First Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Gallia est omnis divisa in partes tres, quarum.")); } - }, "Second Caption", TestIcon.get()); + }, "Second Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Nihil hic munitissimus habendi senatus locus, nihil horum? Sed haec quis possit intrepidus aestimare tellus.")); } - }, "Third Caption", TestIcon.get()); + }, "Third Caption", testIcon.get()); ac.addTab(new VerticalLayout() { { setMargin(true); addComponent(new Label( "Inmensae subtilitatis, obscuris et malesuada fames. Quisque ut dolor gravida, placerat libero vel, euismod.")); } - }, "Custom Caption Style", TestIcon.get()).setStyleName("color1"); + }, "Custom Caption Style", testIcon.get()).setStyleName("color1"); return ac; } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java index ce08d9ba08..758d2de200 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ButtonsAndLinks.java @@ -66,61 +66,62 @@ public class ButtonsAndLinks extends VerticalLayout implements View { button.addStyleName("danger"); row.addComponent(button); + TestIcon testIcon = new TestIcon(10); button = new Button("Small"); button.addStyleName("small"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Large"); button.addStyleName("large"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Top"); button.addStyleName("icon-align-top"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button("Image icon"); - button.setIcon(TestIcon.get(true, 16)); + button.setIcon(testIcon.get(true, 16)); row.addComponent(button); button = new Button("Image icon"); button.addStyleName("icon-align-right"); - button.setIcon(TestIcon.get(true)); + button.setIcon(testIcon.get(true)); row.addComponent(button); button = new Button("Photos"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); row.addComponent(button); button = new Button(); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("icon-only"); row.addComponent(button); button = new Button("Borderless"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("borderless"); row.addComponent(button); button = new Button("Borderless, colored"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("borderless-colored"); row.addComponent(button); button = new Button("Quiet"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("quiet"); row.addComponent(button); button = new Button("Link style"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("link"); row.addComponent(button); button = new Button("Icon on right"); - button.setIcon(TestIcon.get()); + button.setIcon(testIcon.get()); button.addStyleName("icon-align-right"); row.addComponent(button); @@ -154,7 +155,7 @@ public class ButtonsAndLinks extends VerticalLayout implements View { link = new Link("Link with icon", new ExternalResource( "https://vaadin.com")); link.addStyleName("color3"); - link.setIcon(TestIcon.get()); + link.setIcon(testIcon.get()); row.addComponent(link); link = new Link("Small", new ExternalResource("https://vaadin.com")); @@ -166,7 +167,7 @@ public class ButtonsAndLinks extends VerticalLayout implements View { row.addComponent(link); link = new Link(null, new ExternalResource("https://vaadin.com")); - link.setIcon(TestIcon.get()); + link.setIcon(testIcon.get()); link.addStyleName("large"); row.addComponent(link); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java b/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java index 17dfd6cb67..280ddf98b7 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java @@ -4,7 +4,6 @@ import java.text.DateFormatSymbols; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; -import java.util.Map; import java.util.TimeZone; import com.vaadin.annotations.Theme; @@ -51,6 +50,7 @@ import com.vaadin.ui.components.calendar.event.BasicEventProvider; import com.vaadin.ui.components.calendar.event.CalendarEvent; import com.vaadin.ui.components.calendar.handler.BasicDateClickHandler; import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; +import com.vaadin.ui.themes.ValoTheme; /** Calendar component test application */ @Theme("valo-test") @@ -108,7 +108,7 @@ public class CalendarTest extends GridLayout implements View { private Button applyEventButton; - private Mode viewMode = Mode.MONTH; + private Mode viewMode = Mode.WEEK; private BasicEventProvider dataSource; @@ -152,52 +152,11 @@ public class CalendarTest extends GridLayout implements View { setSpacing(true); // handleURLParams(request.getParameterMap()); + testBench = ValoThemeUI.isTestMode(); initContent(); } - private void handleURLParams(Map<String, String[]> parameters) { - testBench = parameters.containsKey("testBench") - || parameters.containsKey("?testBench"); - - if (parameters.containsKey("width")) { - calendarWidth = parameters.get("width")[0]; - } - - if (parameters.containsKey("height")) { - calendarHeight = parameters.get("height")[0]; - } - - if (parameters.containsKey("firstDay")) { - firstDay = Integer.parseInt(parameters.get("firstDay")[0]); - } - - if (parameters.containsKey("lastDay")) { - lastDay = Integer.parseInt(parameters.get("lastDay")[0]); - } - - if (parameters.containsKey("firstHour")) { - firstHour = Integer.parseInt(parameters.get("firstHour")[0]); - } - - if (parameters.containsKey("lastHour")) { - lastHour = Integer.parseInt(parameters.get("lastHour")[0]); - } - - if (parameters.containsKey("locale")) { - String localeArray[] = parameters.get("locale")[0].split("_"); - defaultLocale = new Locale(localeArray[0], localeArray[1]); - setLocale(defaultLocale); - } - - if (parameters.containsKey(("secondsResolution"))) { - useSecondResolution = true; - } - - showWeeklyView = parameters.containsKey("weekly"); - - } - public void initContent() { // Set default Locale for this application if (testBench) { @@ -365,6 +324,9 @@ public class CalendarTest extends GridLayout implements View { Alignment.MIDDLE_LEFT); controlPanel.setComponentAlignment(addNewEvent, Alignment.MIDDLE_LEFT); + Label viewCaption = new Label("Calendar"); + viewCaption.setStyleName(ValoTheme.LABEL_H1); + addComponent(viewCaption); addComponent(controlPanel); addComponent(hl); addComponent(calendarComponent); @@ -645,6 +607,11 @@ public class CalendarTest extends GridLayout implements View { calendar.setTime(today); calendarComponent.getInternalCalendar().setTime(today); + // Calendar getStartDate (and getEndDate) has some strange logic which + // returns Monday of the current internal time if no start date has been + // set + calendarComponent.setStartDate(calendarComponent.getStartDate()); + calendarComponent.setEndDate(calendarComponent.getEndDate()); int rollAmount = calendar.get(GregorianCalendar.DAY_OF_MONTH) - 1; calendar.add(GregorianCalendar.DAY_OF_MONTH, -rollAmount); currentMonthsFirstDate = calendar.getTime(); diff --git a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java index a2daeff2f8..c7a2610a21 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CheckBoxes.java @@ -57,17 +57,18 @@ public class CheckBoxes extends VerticalLayout implements View { check.addStyleName("color1"); row.addComponent(check); + TestIcon testIcon = new TestIcon(30); check = new CheckBox("Custom color", true); check.addStyleName("color2"); - check.setIcon(TestIcon.get()); + check.setIcon(testIcon.get()); row.addComponent(check); check = new CheckBox("With Icon", true); - check.setIcon(TestIcon.get()); + check.setIcon(testIcon.get()); row.addComponent(check); check = new CheckBox(); - check.setIcon(TestIcon.get(true)); + check.setIcon(testIcon.get(true)); row.addComponent(check); check = new CheckBox("Small", true); @@ -94,9 +95,9 @@ public class CheckBoxes extends VerticalLayout implements View { .addItem("Option Two, with a longer caption that should wrap when the components width is explicitly set."); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, explicit width"); @@ -107,9 +108,9 @@ public class CheckBoxes extends VerticalLayout implements View { .addItem("Option Two, with a longer caption that should wrap when the components width is explicitly set."); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose one, small"); @@ -119,9 +120,9 @@ public class CheckBoxes extends VerticalLayout implements View { options.addItem("Option Two"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon("Option Two", TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, small"); @@ -131,9 +132,9 @@ public class CheckBoxes extends VerticalLayout implements View { options.addItem("Option Two"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon("Option Two", TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose one, large"); @@ -143,9 +144,9 @@ public class CheckBoxes extends VerticalLayout implements View { options.addItem("Option Two"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon("Option Two", TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Choose many, large"); @@ -155,9 +156,9 @@ public class CheckBoxes extends VerticalLayout implements View { options.addItem("Option Two"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon("Option Two", TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get(true)); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon("Option Two", testIcon.get()); + options.setItemIcon("Option Three", testIcon.get(true)); row.addComponent(options); options = new OptionGroup("Horizontal items"); @@ -166,9 +167,9 @@ public class CheckBoxes extends VerticalLayout implements View { two = options.addItem("Option Two, with a longer caption"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get()); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get()); row.addComponent(options); options = new OptionGroup("Horizontal items, explicit width"); @@ -179,9 +180,9 @@ public class CheckBoxes extends VerticalLayout implements View { two = options.addItem("Option Two, with a longer caption"); options.addItem("Option Three"); options.select("Option One"); - options.setItemIcon("Option One", TestIcon.get()); - options.setItemIcon(two, TestIcon.get()); - options.setItemIcon("Option Three", TestIcon.get()); + options.setItemIcon("Option One", testIcon.get()); + options.setItemIcon(two, testIcon.get()); + options.setItemIcon("Option Three", testIcon.get()); row.addComponent(options); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java b/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java index b841b0b116..a7fd60ea51 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ColorPickers.java @@ -37,9 +37,11 @@ public class ColorPickers extends VerticalLayout implements View { row.setSpacing(true); addComponent(row); + TestIcon testIcon = new TestIcon(40); + ColorPicker cp = new ColorPicker(); cp.setDefaultCaptionEnabled(true); - cp.setIcon(TestIcon.get()); + cp.setIcon(testIcon.get()); cp.setColor(new Color(138, 73, 115)); row.addComponent(cp); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java b/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java index cafdfe37e0..1b8b290d91 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ComboBoxes.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.themes.valo; -import com.vaadin.data.Container; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.server.ThemeResource; @@ -40,15 +39,13 @@ public class ComboBoxes extends VerticalLayout implements View { row.setSpacing(true); addComponent(row); - Container generatedContainer = ValoThemeTest.generateContainer(200, - false); ComboBox combo = new ComboBox("Normal"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); combo.setNullSelectionAllowed(false); - combo.select(generatedContainer.getItemIds().iterator().next()); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.select(combo.getItemIds().iterator().next()); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.setItemIcon(combo.getItemIds().iterator().next(), new ThemeResource("../runo/icons/16/document.png")); row.addComponent(combo); @@ -60,11 +57,11 @@ public class ComboBoxes extends VerticalLayout implements View { combo = new ComboBox(); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); combo.setNullSelectionAllowed(false); - combo.select(generatedContainer.getItemIds().iterator().next()); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.select(combo.getItemIds().iterator().next()); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.setWidth("240px"); group.addComponent(combo); Button today = new Button("Do It"); @@ -120,41 +117,41 @@ public class ComboBoxes extends VerticalLayout implements View { combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color1"); row.addComponent(combo); combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color2"); row.addComponent(combo); combo = new ComboBox("Custom color"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("color3"); row.addComponent(combo); combo = new ComboBox("Small"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("small"); row.addComponent(combo); combo = new ComboBox("Large"); combo.setInputPrompt("You can type here"); - combo.setContainerDataSource(generatedContainer); - combo.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - combo.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + combo.setContainerDataSource(ValoThemeUI.generateContainer(200, false)); + combo.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + combo.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); combo.addStyleName("large"); row.addComponent(combo); diff --git a/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java b/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java index 75d51ed2a6..52cc43ac28 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java @@ -131,9 +131,11 @@ public class CommonParts extends VerticalLayout implements View { spinnerDesc.setCaption("Spinner"); content.addComponent(spinnerDesc); - Label spinner = new Label(); - spinner.addStyleName("spinner"); - content.addComponent(spinner); + if (!ValoThemeUI.isTestMode()) { + Label spinner = new Label(); + spinner.addStyleName("spinner"); + content.addComponent(spinner); + } return p; } @@ -240,6 +242,7 @@ public class CommonParts extends VerticalLayout implements View { }; style.setCaption("Additional style"); + style.addItem("Dark", styleCommand).setCheckable(true); style.addItem("Success", styleCommand).setCheckable(true); style.addItem("Failure", styleCommand).setCheckable(true); style.addItem("Bar", styleCommand).setCheckable(true); diff --git a/uitest/src/com/vaadin/tests/themes/valo/DateFields.java b/uitest/src/com/vaadin/tests/themes/valo/DateFields.java index ae520e07c2..41aa287f9f 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/DateFields.java +++ b/uitest/src/com/vaadin/tests/themes/valo/DateFields.java @@ -46,16 +46,16 @@ public class DateFields extends VerticalLayout implements View { addComponent(row); DateField date = new DateField("Default resolution"); - date.setValue(new Date()); + setDate(date); row.addComponent(date); date = new DateField("Error"); - date.setValue(new Date()); + setDate(date); date.setComponentError(new UserError("Fix it, now!")); row.addComponent(date); date = new DateField("Error, borderless"); - date.setValue(new Date()); + setDate(date); date.setComponentError(new UserError("Fix it, now!")); date.addStyleName("borderless"); row.addComponent(date); @@ -77,110 +77,120 @@ public class DateFields extends VerticalLayout implements View { group.addComponent(today); date = new DateField("Default resolution, explicit size"); - date.setValue(new Date()); + setDate(date); row.addComponent(date); date.setWidth("260px"); date.setHeight("60px"); date = new DateField("Second resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.SECOND); row.addComponent(date); date = new DateField("Minute resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.MINUTE); row.addComponent(date); date = new DateField("Hour resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.HOUR); row.addComponent(date); date = new DateField("Disabled"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.HOUR); date.setEnabled(false); row.addComponent(date); date = new DateField("Day resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); row.addComponent(date); date = new DateField("Month resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.MONTH); row.addComponent(date); date = new DateField("Year resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.YEAR); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color1"); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color2"); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color3"); row.addComponent(date); date = new DateField("Small"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("small"); row.addComponent(date); date = new DateField("Large"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("large"); row.addComponent(date); date = new DateField("Borderless"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("borderless"); row.addComponent(date); date = new DateField("Week numbers"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.setLocale(new Locale("fi", "fi")); date.setShowISOWeekNumbers(true); row.addComponent(date); date = new DateField("US locale"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.SECOND); date.setLocale(new Locale("en", "US")); row.addComponent(date); date = new DateField("Custom format"); - date.setValue(new Date()); + setDate(date); date.setDateFormat("E dd/MM/yyyy"); row.addComponent(date); date = new InlineDateField("Date picker"); + setDate(date); row.addComponent(date); date = new InlineDateField("Date picker with week numbers"); + setDate(date); date.setLocale(new Locale("fi", "fi")); date.setShowISOWeekNumbers(true); row.addComponent(date); } + private void setDate(DateField date) { + if (ValoThemeUI.isTestMode()) { + date.setValue(new Date(2014 - 1900, 5, 7)); + } else { + date.setValue(new Date()); + } + } + @Override public void enter(ViewChangeEvent event) { // TODO Auto-generated method stub diff --git a/uitest/src/com/vaadin/tests/themes/valo/Forms.java b/uitest/src/com/vaadin/tests/themes/valo/Forms.java index 9451b5c5d3..c5b08902be 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Forms.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Forms.java @@ -47,7 +47,7 @@ public class Forms extends VerticalLayout implements View { setSpacing(true); setMargin(true); - Label title = new Label("Form"); + Label title = new Label("Forms"); title.addStyleName("h1"); addComponent(title); @@ -60,10 +60,10 @@ public class Forms extends VerticalLayout implements View { Label section = new Label("Personal Info"); section.addStyleName("h2"); form.addComponent(section); + StringGenerator sg = new StringGenerator(); TextField name = new TextField("Name"); - name.setValue(ValoThemeTest.nextString(true) + " " - + ValoThemeTest.nextString(true)); + name.setValue(sg.nextString(true) + " " + sg.nextString(true)); name.setWidth("50%"); form.addComponent(name); @@ -72,8 +72,7 @@ public class Forms extends VerticalLayout implements View { form.addComponent(birthday); TextField username = new TextField("Username"); - username.setValue(ValoThemeTest.nextString(false) - + ValoThemeTest.nextString(false)); + username.setValue(sg.nextString(false) + sg.nextString(false)); username.setRequired(true); form.addComponent(username); @@ -89,15 +88,14 @@ public class Forms extends VerticalLayout implements View { form.addComponent(section); TextField email = new TextField("Email"); - email.setValue(ValoThemeTest.nextString(false) + "@" - + ValoThemeTest.nextString(false) + ".com"); + email.setValue(sg.nextString(false) + "@" + sg.nextString(false) + + ".com"); email.setWidth("50%"); email.setRequired(true); form.addComponent(email); TextField location = new TextField("Location"); - location.setValue(ValoThemeTest.nextString(true) + ", " - + ValoThemeTest.nextString(true)); + location.setValue(sg.nextString(true) + ", " + sg.nextString(true)); location.setWidth("50%"); location.setComponentError(new UserError("This address doesn't exist")); form.addComponent(location); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.java b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.java new file mode 100644 index 0000000000..87f24d98d4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUpload.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes.valo; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Upload; + +/** + * + * @since + * @author Vaadin Ltd + */ +@Theme("valo") +public class ImmediateUpload extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + Upload upload = new Upload(); + upload.setId("upload"); + upload.setImmediate(false); + addComponent(upload); + + Upload immediateUpload = new Upload(); + immediateUpload.setId("immediateupload"); + immediateUpload.setImmediate(true); + addComponent(immediateUpload); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Immediate upload should hide the button"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(14238); + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java new file mode 100644 index 0000000000..044f76e335 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes.valo; + +import static org.hamcrest.Matchers.equalToIgnoringCase; +import static org.junit.Assert.assertThat; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.UploadElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test to see if upload immediate mode hides the native file input. + * + * @author Vaadin Ltd + */ +public class ImmediateUploadTest extends MultiBrowserTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return getAllBrowsers(); + } + + @Test + public void fileInputShouldNotBeVisibleInImmediate() + throws InterruptedException { + openTestURL(); + + UploadElement normalUpload = $(UploadElement.class).id("upload"); + UploadElement immediateUpload = $(UploadElement.class).id( + "immediateupload"); + + WebElement normalUploadInput = normalUpload.findElement(By + .cssSelector("input[type='file']")); + WebElement immediateUploadInput = immediateUpload.findElement(By + .cssSelector("input[type='file']")); + + WebElement normalUploadButton = normalUpload.findElement(By + .tagName("div")); + WebElement immediateUploadButton = immediateUpload.findElement(By + .tagName("div")); + + assertThat(normalUploadButton.getCssValue("display"), + equalToIgnoringCase("block")); + assertThat(immediateUploadButton.getCssValue("display"), + equalToIgnoringCase("block")); + + assertThat(normalUploadInput.getCssValue("position"), + equalToIgnoringCase("static")); + assertThat(immediateUploadInput.getCssValue("position"), + equalToIgnoringCase("absolute")); + + } +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java b/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java index f15f43254a..88eea73513 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java +++ b/uitest/src/com/vaadin/tests/themes/valo/MenuBars.java @@ -120,14 +120,16 @@ public class MenuBars extends VerticalLayout implements View { view.addItem("Zoom In", click); view.addItem("Zoom Out", click); + TestIcon testIcon = new TestIcon(50); + MenuItem fav = menubar.addItem("", check); - fav.setIcon(TestIcon.get()); + fav.setIcon(testIcon.get()); fav.setStyleName("icon-only"); fav.setCheckable(true); fav.setChecked(true); fav = menubar.addItem("", check); - fav.setIcon(TestIcon.get()); + fav.setIcon(testIcon.get()); fav.setStyleName("icon-only"); fav.setCheckable(true); fav.setCheckable(true); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Panels.java b/uitest/src/com/vaadin/tests/themes/valo/Panels.java index 74baef066b..8a17244693 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Panels.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Panels.java @@ -40,45 +40,46 @@ public class Panels extends VerticalLayout implements View { row.addStyleName("wrapping"); row.setSpacing(true); addComponent(row); + TestIcon testIcon = new TestIcon(60); Panel panel = new Panel("Normal"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Sized"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.setWidth("10em"); panel.setHeight("250px"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color1"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color2"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Custom Caption"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("color3"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Borderless style"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("borderless"); panel.setContent(panelContent()); row.addComponent(panel); panel = new Panel("Borderless + scroll divider"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("borderless"); panel.addStyleName("scroll-divider"); panel.setContent(panelContentScroll()); @@ -86,13 +87,13 @@ public class Panels extends VerticalLayout implements View { row.addComponent(panel); panel = new Panel("Well style"); - panel.setIcon(TestIcon.get()); + panel.setIcon(testIcon.get()); panel.addStyleName("well"); panel.setContent(panelContent()); row.addComponent(panel); CssLayout layout = new CssLayout(); - layout.setIcon(TestIcon.get()); + layout.setIcon(testIcon.get()); layout.setCaption("Panel style layout"); layout.addStyleName("card"); layout.addComponent(panelContent()); @@ -131,7 +132,7 @@ public class Panels extends VerticalLayout implements View { layout.setWidth("14em"); layout = new CssLayout(); - layout.setIcon(TestIcon.get()); + layout.setIcon(testIcon.get()); layout.setCaption("Well style layout"); layout.addStyleName("well"); layout.addComponent(panelContent()); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Sliders.java b/uitest/src/com/vaadin/tests/themes/valo/Sliders.java index 363c698c32..8ed846e39f 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Sliders.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Sliders.java @@ -158,11 +158,12 @@ public class Sliders extends VerticalLayout implements View { // pb2.setValue(0.6f); row.addComponent(pb2); - ProgressBar pb3 = new ProgressBar(); - pb3.setIndeterminate(true); - pb3.setCaption("Indeterminate"); - row.addComponent(pb3); - + if (!ValoThemeUI.isTestMode()) { + ProgressBar pb3 = new ProgressBar(); + pb3.setIndeterminate(true); + pb3.setCaption("Indeterminate"); + row.addComponent(pb3); + } } float progress = 0; @@ -196,14 +197,21 @@ public class Sliders extends VerticalLayout implements View { @Override public void enter(ViewChangeEvent event) { - getUI().setPollInterval(1000); - update.start(); + if (!ValoThemeUI.isTestMode()) { + getUI().setPollInterval(1000); + update.start(); + } else { + pb.setValue(0.3f); + pb2.setValue(0.6f); + } } @Override public void detach() { - getUI().setPollInterval(-1); - update.interrupt(); + if (!ValoThemeUI.isTestMode()) { + getUI().setPollInterval(-1); + update.interrupt(); + } super.detach(); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java b/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java new file mode 100644 index 0000000000..7e5cc0f691 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/StringGenerator.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes.valo; + +public class StringGenerator { + static String[] strings = new String[] { "lorem", "ipsum", "dolor", "sit", + "amet", "consectetur", "quid", "securi", "etiam", "tamquam", "eu", + "fugiat", "nulla", "pariatur" }; + int stringCount = -1; + + String nextString(boolean capitalize) { + if (++stringCount >= strings.length) { + stringCount = 0; + } + return capitalize ? strings[stringCount].substring(0, 1).toUpperCase() + + strings[stringCount].substring(1) : strings[stringCount]; + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/Tables.java b/uitest/src/com/vaadin/tests/themes/valo/Tables.java index 6aa02a7f74..62ef67f9f3 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Tables.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Tables.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -40,16 +40,15 @@ import com.vaadin.ui.VerticalLayout; public class Tables extends VerticalLayout implements View { - static final Container normalContainer = ValoThemeTest.generateContainer( - 200, false); - static final Container hierarchicalContainer = ValoThemeTest - .generateContainer(200, true); + final Container normalContainer = ValoThemeUI.generateContainer(200, false); + final Container hierarchicalContainer = ValoThemeUI.generateContainer(200, + true); CheckBox hierarchical = new CheckBox("Hierarchical"); CheckBox footer = new CheckBox("Footer", true); CheckBox sized = new CheckBox("Sized"); CheckBox expandRatios = new CheckBox("Expand ratios"); - CheckBox stripes = new CheckBox("Sripes", true); + CheckBox stripes = new CheckBox("Stripes", true); CheckBox verticalLines = new CheckBox("Vertical lines", true); CheckBox horizontalLines = new CheckBox("Horizontal lines", true); CheckBox borderless = new CheckBox("Borderless"); @@ -140,7 +139,7 @@ public class Tables extends VerticalLayout implements View { table.setColumnCollapsingAllowed(true); table.setColumnReorderingAllowed(true); table.setPageLength(6); - table.addActionHandler(ValoThemeTest.getActionHandler()); + table.addActionHandler(ValoThemeUI.getActionHandler()); table.setDragMode(TableDragMode.MULTIROW); table.setDropHandler(new DropHandler() { @Override @@ -153,9 +152,8 @@ public class Tables extends VerticalLayout implements View { Notification.show(event.getTransferable().toString()); } }); - table.setColumnAlignment(ValoThemeTest.DESCRIPTION_PROPERTY, - Align.RIGHT); - table.setColumnAlignment(ValoThemeTest.INDEX_PROPERTY, Align.CENTER); + table.setColumnAlignment(ValoThemeUI.DESCRIPTION_PROPERTY, Align.RIGHT); + table.setColumnAlignment(ValoThemeUI.INDEX_PROPERTY, Align.CENTER); table.removeContainerProperty("textfield"); table.addContainerProperty("textfield", TextField.class, null); @@ -186,11 +184,11 @@ public class Tables extends VerticalLayout implements View { table.setFooterVisible(footer); if (footer) { - table.setColumnFooter(ValoThemeTest.CAPTION_PROPERTY, "caption"); - table.setColumnFooter(ValoThemeTest.DESCRIPTION_PROPERTY, + table.setColumnFooter(ValoThemeUI.CAPTION_PROPERTY, "caption"); + table.setColumnFooter(ValoThemeUI.DESCRIPTION_PROPERTY, "description"); - table.setColumnFooter(ValoThemeTest.ICON_PROPERTY, "icon"); - table.setColumnFooter(ValoThemeTest.INDEX_PROPERTY, "index"); + table.setColumnFooter(ValoThemeUI.ICON_PROPERTY, "icon"); + table.setColumnFooter(ValoThemeUI.INDEX_PROPERTY, "index"); } if (sized) { @@ -205,9 +203,9 @@ public class Tables extends VerticalLayout implements View { table.setWidth("100%"); } } - table.setColumnExpandRatio(ValoThemeTest.CAPTION_PROPERTY, + table.setColumnExpandRatio(ValoThemeUI.CAPTION_PROPERTY, expandRatios ? 1.0f : 0); - table.setColumnExpandRatio(ValoThemeTest.DESCRIPTION_PROPERTY, + table.setColumnExpandRatio(ValoThemeUI.DESCRIPTION_PROPERTY, expandRatios ? 1.0f : 0); if (!stripes) { @@ -262,14 +260,14 @@ public class Tables extends VerticalLayout implements View { if (rowCaption) { table.setRowHeaderMode(RowHeaderMode.PROPERTY); - table.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); + table.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); } else { table.setItemCaptionPropertyId(null); } if (rowIcon) { table.setRowHeaderMode(RowHeaderMode.ICON_ONLY); - table.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + table.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); } else { table.setItemIconPropertyId(null); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java b/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java index 24a249d90e..5e77292471 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Tabsheets.java @@ -149,12 +149,15 @@ public class Tabsheets extends VerticalLayout implements View { static TabSheet getTabSheet(boolean caption, String style, boolean closable, boolean scrolling, boolean icon, boolean disable) { + TestIcon testIcon = new TestIcon(60); + TabSheet ts = new TabSheet(); ts.addStyleName(style); + StringGenerator sg = new StringGenerator(); for (int i = 1; i <= (scrolling ? 10 : 3); i++) { - String tabcaption = caption ? ValoThemeTest.nextString(true) + " " - + ValoThemeTest.nextString(false) : null; + String tabcaption = caption ? sg.nextString(true) + " " + + sg.nextString(false) : null; VerticalLayout content = new VerticalLayout(); content.setMargin(true); @@ -174,7 +177,7 @@ public class Tabsheets extends VerticalLayout implements View { } if (icon) { - t.setIcon(TestIcon.get(false)); + t.setIcon(testIcon.get(false)); } } diff --git a/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java b/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java index 18b834f1bf..469f6bc31d 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java +++ b/uitest/src/com/vaadin/tests/themes/valo/TestIcon.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2013 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -24,21 +24,27 @@ import com.vaadin.server.Resource; import com.vaadin.server.ThemeResource; /** - * + * * @since * @author Vaadin Ltd */ public class TestIcon { - public static Resource get() { + int iconCount = 0; + + public TestIcon(int startIndex) { + iconCount = startIndex; + } + + public Resource get() { return get(false, 32); } - public static Resource get(boolean isImage) { + public Resource get(boolean isImage) { return get(isImage, 32); } - public static Resource get(boolean isImage, int imageSize) { + public Resource get(boolean isImage, int imageSize) { if (!isImage) { if (++iconCount >= ICONS.size()) { iconCount = 0; @@ -51,5 +57,4 @@ public class TestIcon { static List<FontAwesome> ICONS = Collections.unmodifiableList(Arrays .asList(FontAwesome.values())); - static int iconCount = 0; } diff --git a/uitest/src/com/vaadin/tests/themes/valo/TextFields.java b/uitest/src/com/vaadin/tests/themes/valo/TextFields.java index cbe7a8a0b3..f8606bb7c9 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/TextFields.java +++ b/uitest/src/com/vaadin/tests/themes/valo/TextFields.java @@ -30,6 +30,8 @@ import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; public class TextFields extends VerticalLayout implements View { + private TestIcon testIcon = new TestIcon(140); + public TextFields() { setMargin(true); @@ -44,7 +46,7 @@ public class TextFields extends VerticalLayout implements View { TextField tf = new TextField("Normal"); tf.setInputPrompt("First name"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Custom color"); @@ -87,45 +89,45 @@ public class TextFields extends VerticalLayout implements View { tf = new TextField("Large"); tf.setValue("Field value"); tf.addStyleName("large"); - tf.setIcon(TestIcon.get(true)); + tf.setIcon(testIcon.get(true)); row.addComponent(tf); tf = new TextField("Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Large, Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("large"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Small, Icon inside"); tf.setInputPrompt("Ooh, an icon"); tf.addStyleName("small"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("16px supported by default"); tf.setInputPrompt("Image icon"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get(true, 16)); + tf.setIcon(testIcon.get(true, 16)); row.addComponent(tf); tf = new TextField(); tf.setValue("Font, no caption"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField(); tf.setValue("Image, no caption"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get(true, 16)); + tf.setIcon(testIcon.get(true, 16)); row.addComponent(tf); CssLayout group = new CssLayout(); @@ -135,7 +137,7 @@ public class TextFields extends VerticalLayout implements View { tf = new TextField(); tf.setInputPrompt("Grouped with a button"); tf.addStyleName("inline-icon"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); tf.setWidth("260px"); group.addComponent(tf); @@ -147,7 +149,7 @@ public class TextFields extends VerticalLayout implements View { tf.setInputPrompt("Write here…"); tf.addStyleName("inline-icon"); tf.addStyleName("borderless"); - tf.setIcon(TestIcon.get()); + tf.setIcon(testIcon.get()); row.addComponent(tf); tf = new TextField("Right-aligned"); @@ -196,7 +198,7 @@ public class TextFields extends VerticalLayout implements View { ta = new TextArea("Inline icon"); ta.setInputPrompt("Inline icon not really working"); ta.addStyleName("inline-icon"); - ta.setIcon(TestIcon.get()); + ta.setIcon(testIcon.get()); row.addComponent(ta); ta = new TextArea("Custom color"); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Trees.java b/uitest/src/com/vaadin/tests/themes/valo/Trees.java index bb406e4f39..cb5657660a 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Trees.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Trees.java @@ -45,12 +45,12 @@ public class Trees extends VerticalLayout implements View { Tree tree = new Tree(); tree.setSelectable(true); tree.setMultiSelect(true); - Container generateContainer = ValoThemeTest.generateContainer(10, true); + Container generateContainer = ValoThemeUI.generateContainer(10, true); tree.setContainerDataSource(generateContainer); tree.setDragMode(TreeDragMode.NODE); row.addComponent(tree); - tree.setItemCaptionPropertyId(ValoThemeTest.CAPTION_PROPERTY); - tree.setItemIconPropertyId(ValoThemeTest.ICON_PROPERTY); + tree.setItemCaptionPropertyId(ValoThemeUI.CAPTION_PROPERTY); + tree.setItemIconPropertyId(ValoThemeUI.ICON_PROPERTY); tree.expandItem(generateContainer.getItemIds().iterator().next()); tree.setDropHandler(new DropHandler() { @@ -66,7 +66,7 @@ public class Trees extends VerticalLayout implements View { }); // Add actions (context menu) - tree.addActionHandler(ValoThemeTest.getActionHandler()); + tree.addActionHandler(ValoThemeUI.getActionHandler()); } @Override diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java b/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java index 222dd90e49..1676d121af 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoMiscTests.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -70,7 +70,7 @@ public class ValoMiscTests extends UI { TreeTable table = new TreeTable(); table.setWidth("100%"); - table.setContainerDataSource(Tables.hierarchicalContainer); + table.setContainerDataSource(ValoThemeUI.generateContainer(200, true)); Tables.configure(table, true, false, false, true, true, true, false, true, false, false, false, false, false); layout.addComponent(table); diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeTest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java index 014b1acac8..501b5f573b 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -36,13 +36,14 @@ import com.vaadin.navigator.ViewChangeListener; import com.vaadin.server.FontAwesome; import com.vaadin.server.Page; import com.vaadin.server.Resource; +import com.vaadin.server.Responsive; +import com.vaadin.server.ThemeResource; import com.vaadin.server.VaadinRequest; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.CssLayout; @@ -50,22 +51,45 @@ import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.MenuBar; import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.NativeSelect; import com.vaadin.ui.Notification; import com.vaadin.ui.UI; +import com.vaadin.ui.themes.ValoTheme; @Theme("tests-valo") @Title("Valo Theme Test") @PreserveOnRefresh -public class ValoThemeTest extends UI { +public class ValoThemeUI extends UI { + + private boolean testMode = false; + + private static LinkedHashMap<String, String> themeVariants = new LinkedHashMap<String, String>(); + static { + themeVariants.put("tests-valo", "Default"); + themeVariants.put("tests-valo-blueprint", "Blueprint"); + themeVariants.put("tests-valo-dark", "Dark"); + themeVariants.put("tests-valo-facebook", "Facebook"); + themeVariants.put("tests-valo-flatdark", "Flat dark"); + themeVariants.put("tests-valo-flat", "Flat"); + themeVariants.put("tests-valo-metro", "Metro"); + } + private TestIcon testIcon = new TestIcon(100); ValoMenuLayout root = new ValoMenuLayout(); ComponentContainer viewDisplay = root.getContentContainer(); CssLayout menu = new CssLayout(); + CssLayout menuItemsLayout = new CssLayout(); + { + menu.setId("testMenu"); + } private Navigator navigator; private LinkedHashMap<String, String> menuItems = new LinkedHashMap<String, String>(); @Override protected void init(VaadinRequest request) { + if (request.getParameter("test") != null) { + testMode = true; + } // Show .v-app-loading valo-menu-badge // try { // Thread.sleep(2000); @@ -73,11 +97,12 @@ public class ValoThemeTest extends UI { // e.printStackTrace(); // } + Responsive.makeResponsive(this); + getPage().setTitle("Valo Theme Test"); setContent(root); root.setWidth("100%"); - root.addMenu(buildTestMenu()); root.addMenu(buildMenu()); navigator = new Navigator(this, viewDisplay); @@ -118,13 +143,14 @@ public class ValoThemeTest extends UI { @Override public void afterViewChange(ViewChangeEvent event) { - for (Iterator<Component> it = menu.iterator(); it.hasNext();) { + for (Iterator<Component> it = menuItemsLayout.iterator(); it + .hasNext();) { it.next().removeStyleName("selected"); } for (Entry<String, String> item : menuItems.entrySet()) { if (event.getViewName().equals(item.getKey())) { - for (Iterator<Component> it = menu.iterator(); it - .hasNext();) { + for (Iterator<Component> it = menuItemsLayout + .iterator(); it.hasNext();) { Component c = it.next(); if (c.getCaption() != null && c.getCaption().startsWith( @@ -141,6 +167,10 @@ public class ValoThemeTest extends UI { } + static boolean isTestMode() { + return ((ValoThemeUI) getCurrent()).testMode; + } + Component buildTestMenu() { CssLayout menu = new CssLayout(); menu.addStyleName("large-icons"); @@ -201,31 +231,45 @@ public class ValoThemeTest extends UI { top.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); top.addStyleName("valo-menu-title"); menu.addComponent(top); + menu.addComponent(createThemeSelect()); - Label title = new Label("Vaadin<br><strong>Valo Theme Styles</strong>", + Button showMenu = new Button("Menu", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + if (menu.getStyleName().contains("valo-menu-visible")) { + menu.removeStyleName("valo-menu-visible"); + } else { + menu.addStyleName("valo-menu-visible"); + } + } + }); + showMenu.addStyleName(ValoTheme.BUTTON_PRIMARY); + showMenu.addStyleName(ValoTheme.BUTTON_SMALL); + showMenu.addStyleName("valo-menu-toggle"); + showMenu.setIcon(FontAwesome.LIST); + menu.addComponent(showMenu); + + Label title = new Label("<h3>Vaadin <strong>Valo Theme</strong></h3>", ContentMode.HTML); title.setSizeUndefined(); top.addComponent(title); top.setExpandRatio(title, 1); MenuBar settings = new MenuBar(); - MenuItem settingsItem = settings.addItem("", FontAwesome.COG, null); - settingsItem.setStyleName("icon-only"); + settings.addStyleName("user-menu"); + StringGenerator sg = new StringGenerator(); + MenuItem settingsItem = settings.addItem( + sg.nextString(true) + " " + sg.nextString(true) + + sg.nextString(false), new ThemeResource( + "../tests-valo/img/profile-pic-300px.jpg"), null); settingsItem.addItem("Edit Profile", null); settingsItem.addItem("Preferences", null); settingsItem.addSeparator(); settingsItem.addItem("Sign Out", null); - top.addComponent(settings); + menu.addComponent(settings); - final CheckBox enabled = new CheckBox("Enabled", true); - enabled.setDescription("Enable or disable the components on the right side"); - menu.addComponent(enabled); - enabled.addValueChangeListener(new ValueChangeListener() { - @Override - public void valueChange(ValueChangeEvent event) { - viewDisplay.setEnabled(enabled.getValue()); - } - }); + menuItemsLayout.setPrimaryStyleName("valo-menuitems"); + menu.addComponent(menuItemsLayout); Label label = null; int count = -1; @@ -235,7 +279,7 @@ public class ValoThemeTest extends UI { label.setPrimaryStyleName("valo-menu-subtitle"); label.addStyleName("h4"); label.setSizeUndefined(); - menu.addComponent(label); + menuItemsLayout.addComponent(label); } if (item.getKey().equals("panels")) { label.setValue(label.getValue() @@ -246,7 +290,7 @@ public class ValoThemeTest extends UI { label.setPrimaryStyleName("valo-menu-subtitle"); label.addStyleName("h4"); label.setSizeUndefined(); - menu.addComponent(label); + menuItemsLayout.addComponent(label); } if (item.getKey().equals("calendar")) { label.setValue(label.getValue() @@ -257,7 +301,7 @@ public class ValoThemeTest extends UI { label.setPrimaryStyleName("valo-menu-subtitle"); label.addStyleName("h4"); label.setSizeUndefined(); - menu.addComponent(label); + menuItemsLayout.addComponent(label); } Button b = new Button(item.getValue(), new ClickListener() { @Override @@ -271,8 +315,8 @@ public class ValoThemeTest extends UI { } b.setHtmlContentAllowed(true); b.setPrimaryStyleName("valo-menu-item"); - b.setIcon(TestIcon.get()); - menu.addComponent(b); + b.setIcon(testIcon.get()); + menuItemsLayout.addComponent(b); count++; } label.setValue(label.getValue() + " <span class=\"valo-menu-badge\">" @@ -281,17 +325,25 @@ public class ValoThemeTest extends UI { return menu; } - static String[] strings = new String[] { "lorem", "ipsum", "dolor", "sit", - "amet", "consectetur", "quid", "securi", "etiam", "tamquam", "eu", - "fugiat", "nulla", "pariatur" }; - static int stringCount = -1; - - static String nextString(boolean capitalize) { - if (++stringCount >= strings.length) { - stringCount = 0; + private Component createThemeSelect() { + final NativeSelect ns = new NativeSelect(); + ns.setNullSelectionAllowed(false); + ns.setId("themeSelect"); + ns.addContainerProperty("caption", String.class, ""); + ns.setItemCaptionPropertyId("caption"); + for (String identifier : themeVariants.keySet()) { + ns.addItem(identifier).getItemProperty("caption") + .setValue(themeVariants.get(identifier)); } - return capitalize ? strings[stringCount].substring(0, 1).toUpperCase() - + strings[stringCount].substring(1) : strings[stringCount]; + + ns.setValue("tests-valo"); + ns.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + setTheme((String) ns.getValue()); + } + }); + return ns; } static Handler actionHandler = new Handler() { @@ -324,9 +376,10 @@ public class ValoThemeTest extends UI { @SuppressWarnings("unchecked") static Container generateContainer(final int size, final boolean hierarchical) { + TestIcon testIcon = new TestIcon(90); IndexedContainer container = hierarchical ? new HierarchicalContainer() : new IndexedContainer(); - + StringGenerator sg = new StringGenerator(); container.addContainerProperty(CAPTION_PROPERTY, String.class, null); container.addContainerProperty(ICON_PROPERTY, Resource.class, null); container.addContainerProperty(INDEX_PROPERTY, Integer.class, null); @@ -335,15 +388,15 @@ public class ValoThemeTest extends UI { for (int i = 1; i < size + 1; i++) { Item item = container.addItem(i); item.getItemProperty(CAPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false)); + sg.nextString(true) + " " + sg.nextString(false)); item.getItemProperty(INDEX_PROPERTY).setValue(i); item.getItemProperty(DESCRIPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false) + " " - + nextString(false)); - item.getItemProperty(ICON_PROPERTY).setValue(TestIcon.get()); + sg.nextString(true) + " " + sg.nextString(false) + " " + + sg.nextString(false)); + item.getItemProperty(ICON_PROPERTY).setValue(testIcon.get()); } container.getItem(container.getIdByIndex(0)) - .getItemProperty(ICON_PROPERTY).setValue(TestIcon.get()); + .getItemProperty(ICON_PROPERTY).setValue(testIcon.get()); if (hierarchical) { for (int i = 1; i < size + 1; i++) { @@ -351,11 +404,37 @@ public class ValoThemeTest extends UI { String id = i + " -> " + j; Item child = container.addItem(id); child.getItemProperty(CAPTION_PROPERTY).setValue( - nextString(true) + " " + nextString(false)); + sg.nextString(true) + " " + sg.nextString(false)); child.getItemProperty(ICON_PROPERTY).setValue( - TestIcon.get()); - ((Hierarchical) container).setChildrenAllowed(id, false); + testIcon.get()); + // ((Hierarchical) container).setChildrenAllowed(id, false); ((Hierarchical) container).setParent(id, i); + + for (int k = 1; k < 6; k++) { + String id2 = id + " -> " + k; + child = container.addItem(id2); + child.getItemProperty(CAPTION_PROPERTY).setValue( + sg.nextString(true) + " " + + sg.nextString(false)); + child.getItemProperty(ICON_PROPERTY).setValue( + testIcon.get()); + // ((Hierarchical) container) + // .setChildrenAllowed(id, false); + ((Hierarchical) container).setParent(id2, id); + + for (int l = 1; l < 5; l++) { + String id3 = id2 + " -> " + l; + child = container.addItem(id3); + child.getItemProperty(CAPTION_PROPERTY).setValue( + sg.nextString(true) + " " + + sg.nextString(false)); + child.getItemProperty(ICON_PROPERTY).setValue( + testIcon.get()); + // ((Hierarchical) container) + // .setChildrenAllowed(id, false); + ((Hierarchical) container).setParent(id3, id2); + } + } } } } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java new file mode 100644 index 0000000000..fdb2eabeee --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java @@ -0,0 +1,239 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.themes.valo; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CssLayoutElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TreeElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ValoThemeUITest extends MultiBrowserTest { + + @Test + public void labels() throws Exception { + openTestURL("test"); + open("Labels"); + compareScreen("labels"); + } + + @Test + public void buttonsLinks() throws Exception { + openTestURL("test"); + open("Buttons & Links", "Buttons"); + compareScreen("buttonsLinks"); + } + + @Test + public void textFields() throws Exception { + openTestURL("test"); + open("Text Fields <span class=\"valo-menu-badge\">123</span>", + "Text Fields"); + compareScreen("textFields"); + } + + @Test + public void common() throws Exception { + openTestURL("test"); + open("Common UI Elements"); + compareScreen("common"); + } + + @Test + public void datefields() throws Exception { + openTestURL("test"); + open("Date Fields"); + // Note that this can look broken in IE9 because of some browser + // rendering issue... The problem seems to be in the customized + // horizontal layout in the test app + compareScreen("datefields"); + } + + @Test + public void comboboxes() throws Exception { + openTestURL("test"); + open("Combo Boxes"); + compareScreen("comboboxes"); + } + + @Test + public void selects() throws Exception { + openTestURL("test"); + open("Selects"); + compareScreen("selects"); + } + + @Test + public void checkboxes() throws Exception { + openTestURL("test"); + open("Check Boxes & Option Groups", "Check Boxes"); + compareScreen("checkboxes"); + } + + @Test + public void sliders() throws Exception { + openTestURL("test"); + open("Sliders & Progress Bars", "Sliders"); + compareScreen("sliders"); + } + + @Test + public void colorpickers() throws Exception { + openTestURL("test"); + open("Color Pickers"); + compareScreen("colorpickers"); + } + + @Test + public void menubars() throws Exception { + openTestURL("test"); + open("Menu Bars"); + compareScreen("menubars"); + } + + @Test + public void trees() throws Exception { + openTestURL("test"); + open("Trees"); + selectTreeNodeByCaption("Quid securi"); + compareScreen("trees"); + } + + private void selectTreeNodeByCaption(String string) { + WebElement e = $(TreeElement.class).first().findElement( + By.xpath("//div[@class='v-tree-node-caption']//span[text()='" + + string + "']")); + e.click(); + } + + @Test + public void tables() throws Exception { + openTestURL("test"); + open("Tables"); + compareScreen("tables"); + } + + @Test + public void dragging() throws Exception { + openTestURL("test"); + open("Drag and Drop", "Dragging Components"); + compareScreen("dragging"); + } + + @Test + public void panels() throws Exception { + openTestURL("test"); + open("Panels", "Panels & Layout panels"); + compareScreen("panels"); + } + + @Test + public void splitpanels() throws Exception { + openTestURL("test"); + open("Split Panels"); + compareScreen("splitpanels"); + } + + @Test + public void tabs() throws Exception { + openTestURL("test"); + open("Tabs <span class=\"valo-menu-badge\">123</span>", "Tabs"); + compareScreen("tabs"); + } + + @Test + public void accordions() throws Exception { + openTestURL("test"); + open("Accordions"); + compareScreen("accordions"); + } + + @Test + public void popupviews() throws Exception { + openTestURL("test"); + open("Popup Views"); + scrollTo(500, 0); + compareScreen("popupviews"); + } + + @Test + public void calendar() throws Exception { + openTestURL("test"); + scrollTo(500, 0); + open("Calendar"); + + compareScreen("calendar"); + } + + @Test + public void forms() throws Exception { + openTestURL("test"); + scrollTo(500, 0); + open("Forms"); + compareScreen("forms"); + } + + private void open(String link) { + open(link, link); + } + + private void open(String link, String caption) { + open(link, caption, 10); + } + + // FIXME: Remove this once click works properly on IE... + private void open(String link, String caption, int tries) { + if (tries <= 0) { + throw new RuntimeException( + "Tried many times but was not able to click the link..."); + } + + $(ButtonElement.class).caption(link).first().click(); + CssLayoutElement content = wrap(CssLayoutElement.class, + findElement(By.className("valo-content"))); + LabelElement captionElem = content.$(LabelElement.class).first(); + if (!captionElem.getText().equals(caption)) { + // IE ... why you fail clicks + System.err.println("Extra click needed on '" + link + + "' on remote " + getDesiredCapabilities() + " " + + getRemoteControlName()); + + open(link, caption, tries - 1); + } + } + + private void scrollTo(int top, int left) { + CssLayoutElement testMenu = $(CssLayoutElement.class).id("testMenu"); + + testBenchElement(testMenu).scroll(top); + testBenchElement(testMenu).scrollLeft(left); + } + + @Override + protected boolean requireWindowFocusForIE() { + return true; + } + + @Override + protected boolean usePersistentHoverForIE() { + return false; + } + +} diff --git a/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java b/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java index b9fc788008..af7a303629 100644 --- a/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java +++ b/uitest/src/com/vaadin/tests/tooltip/AdjacentElementsWithTooltipsTest.java @@ -69,7 +69,6 @@ public class AdjacentElementsWithTooltipsTest extends MultiBrowserTest { } private ButtonElement getButton(String caption) { - return $(ButtonElement.class) - .caption(caption).first(); + return $(ButtonElement.class).caption(caption).first(); } } diff --git a/uitest/src/com/vaadin/tests/tooltip/ButtonTooltips.java b/uitest/src/com/vaadin/tests/tooltip/ButtonTooltips.java index d212a13058..c341aa689b 100644 --- a/uitest/src/com/vaadin/tests/tooltip/ButtonTooltips.java +++ b/uitest/src/com/vaadin/tests/tooltip/ButtonTooltips.java @@ -1,14 +1,18 @@ package com.vaadin.tests.tooltip; -import com.vaadin.tests.components.TestBase; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.VerticalLayout; -public class ButtonTooltips extends TestBase { +public class ButtonTooltips extends AbstractTestUI { + + public static final String shortDescription = "Another"; + public static final String longDescription = "long descidescidescpription"; @Override - protected String getDescription() { + protected String getTestDescription() { return "Button tooltip's size gets messed up if moving from one tooltip to another before a timer expires."; } @@ -18,12 +22,12 @@ public class ButtonTooltips extends TestBase { } @Override - protected void setup() { + protected void setup(VaadinRequest request) { VerticalLayout vl = new VerticalLayout(); Button button = new Button("One"); - button.setDescription("long descidescidescpription"); + button.setDescription(longDescription); Button button2 = new Button("Two"); - button2.setDescription("Another"); + button2.setDescription(shortDescription); vl.addComponent(button); vl.addComponent(button2); vl.setComponentAlignment(button, Alignment.TOP_RIGHT); diff --git a/uitest/src/com/vaadin/tests/tooltip/ButtonTooltipsTest.java b/uitest/src/com/vaadin/tests/tooltip/ButtonTooltipsTest.java index d64dd900a7..08436b1332 100644 --- a/uitest/src/com/vaadin/tests/tooltip/ButtonTooltipsTest.java +++ b/uitest/src/com/vaadin/tests/tooltip/ButtonTooltipsTest.java @@ -1,12 +1,12 @@ /* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -26,7 +26,7 @@ import com.vaadin.tests.tb3.TooltipTest; /** * Tests that tooltip sizes do not change when moving between adjacent elements - * + * * @author Vaadin Ltd */ public class ButtonTooltipsTest extends TooltipTest { @@ -38,12 +38,12 @@ public class ButtonTooltipsTest extends TooltipTest { WebElement buttonOne = $(ButtonElement.class).caption("One").first(); WebElement buttonTwo = $(ButtonElement.class).caption("Two").first(); - checkTooltip(buttonOne, "long descidescidescpription"); + checkTooltip(buttonOne, ButtonTooltips.longDescription); int originalWidth = getTooltipElement().getSize().getWidth(); int originalHeight = getTooltipElement().getSize().getHeight(); clearTooltip(); - checkTooltip(buttonTwo, "Another"); + checkTooltip(buttonTwo, ButtonTooltips.shortDescription); moveMouseTo(buttonOne, 5, 5); sleep(100); assertThat(getTooltipElement().getSize().getWidth(), is(originalWidth)); diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindow.java index cd2cc7d060..690b65432a 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java +++ b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindow.java @@ -1,12 +1,12 @@ -/* +/* * Copyright 2000-2014 Vaadin Ltd. - * + * * 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 - * + * * http://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 @@ -14,7 +14,7 @@ * the License. */ -package com.vaadin.tests.components.window; +package com.vaadin.tests.tooltip; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUI; @@ -41,9 +41,6 @@ public class TooltipInWindow extends AbstractTestUI { TextField tf = new TextField("TextField with a tooltip"); tf.setDescription("My tooltip"); tf.setId(id); - getTooltipConfiguration().setOpenDelay(0); - getTooltipConfiguration().setQuickOpenDelay(0); - getTooltipConfiguration().setCloseTimeout(1000); return tf; } @@ -54,7 +51,7 @@ public class TooltipInWindow extends AbstractTestUI { @Override protected Integer getTicketNumber() { - return Integer.valueOf(9172); + return 9172; } } diff --git a/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java new file mode 100644 index 0000000000..1c50bf5486 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tooltip/TooltipInWindowTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.tooltip; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.TooltipTest; + +/** + * Test if tooltips in subwindows behave correctly + * + * @author Vaadin Ltd + */ +public class TooltipInWindowTest extends TooltipTest { + + @Test + public void testTooltipsInSubWindow() throws Exception { + openTestURL(); + + WebElement textfield = vaadinElementById("tf1"); + + checkTooltip(textfield, "My tooltip"); + + ensureVisibleTooltipPositionedCorrectly(textfield); + + clearTooltip(); + + checkTooltip(textfield, "My tooltip"); + + clearTooltip(); + } + + private WebElement getTooltipContainerElement() { + return getDriver().findElement(By.className("v-tooltip")); + } + + private void ensureVisibleTooltipPositionedCorrectly(WebElement textfield) + throws InterruptedException { + int tooltipX = getTooltip().getLocation().getX(); + int textfieldX = textfield.getLocation().getX(); + assertGreaterOrEqual("Tooltip should be positioned on the textfield (" + + tooltipX + " < " + textfieldX + ")", tooltipX, textfieldX); + } + + private void ensureHiddenTooltipPositionedCorrectly() { + int tooltipX = getTooltipContainerElement().getLocation().getX(); + assertLessThanOrEqual( + "Tooltip should be positioned outside of viewport (was at " + + tooltipX + ")", tooltipX, -1000); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml index fd52e5cd0e..2c25c54e04 100644 --- a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml +++ b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml @@ -13,4 +13,9 @@ <when-type-is class="com.vaadin.client.communication.PushConnection" /> </replace-with> + <replace-with + class="com.vaadin.tests.widgetset.client.MockApplicationConnection"> + <when-type-is class="com.vaadin.client.ApplicationConnection" /> + </replace-with> + </module> diff --git a/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java b/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java new file mode 100644 index 0000000000..4ee5b71387 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.client; + +import java.util.Date; +import java.util.logging.Logger; + +import com.google.gwt.json.client.JSONObject; +import com.google.gwt.json.client.JSONValue; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ValueMap; +import com.vaadin.shared.ApplicationConstants; +import com.vaadin.tests.widgetset.server.csrf.ui.CsrfTokenDisabled; + +/** + * Mock ApplicationConnection for several issues where we need to hack it. + * + * @since + * @author Vaadin Ltd + */ +public class MockApplicationConnection extends ApplicationConnection { + + private static final Logger LOGGER = Logger + .getLogger(MockApplicationConnection.class.getName()); + + // The last token received from the server. + private String lastCsrfTokenReceiver; + + // The last token sent to the server. + private String lastCsrfTokenSent; + + /** + * Provide the last token received from the server. <br/> + * We added this to test the change done on CSRF token. + * + * @see CsrfTokenDisabled + */ + public String getLastCsrfTokenReceiver() { + return lastCsrfTokenReceiver; + } + + /** + * Provide the last token sent to the server. <br/> + * We added this to test the change done on CSRF token. + * + * @see CsrfTokenDisabled + */ + public String getLastCsrfTokenSent() { + return lastCsrfTokenSent; + } + + @Override + protected void handleUIDLMessage(Date start, String jsonText, ValueMap json) { + lastCsrfTokenReceiver = json + .getString(ApplicationConstants.UIDL_SECURITY_TOKEN_ID); + + super.handleUIDLMessage(start, jsonText, json); + } + + @Override + protected void doUidlRequest(String uri, JSONObject payload) { + JSONValue jsonValue = payload.get(ApplicationConstants.CSRF_TOKEN); + lastCsrfTokenSent = jsonValue != null ? jsonValue.toString() : null; + + super.doUidlRequest(uri, payload); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java index 0ef4b664ac..7758cdc2ac 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java @@ -284,11 +284,12 @@ public class SerializerTestConnector extends AbstractExtensionConnector { public void onStateChanged(StateChangeEvent stateChangeEvent) { rpc.log("state.booleanValue: " + getState().booleanValue); rpc.log("state.booleanObjectValue: " + getState().booleanObjectValue); - rpc.log("state.booleanArray: " + getState().booleanArray); + rpc.log("state.booleanArray: " + + Arrays.toString(getState().booleanArray)); rpc.log("state.byteValue: " + getState().byteValue); rpc.log("state.byteObjectValue: " + getState().byteObjectValue); - rpc.log("state.byteArray: " + getState().byteArray); + rpc.log("state.byteArray: " + Arrays.toString(getState().byteArray)); rpc.log("state.charValue: " + getState().charValue); rpc.log("state.charObjectValue: " + getState().charObjectValue); @@ -296,19 +297,19 @@ public class SerializerTestConnector extends AbstractExtensionConnector { rpc.log("state.intValue: " + getState().intValue); rpc.log("state.intObjectValue: " + getState().intObjectValue); - rpc.log("state.intArray: " + getState().intArray); + rpc.log("state.intArray: " + Arrays.toString(getState().intArray)); rpc.log("state.longValue: " + getState().longValue); rpc.log("state.longObjectValue: " + getState().longObjectValue); - rpc.log("state.longArray: " + getState().longArray); + rpc.log("state.longArray: " + Arrays.toString(getState().longArray)); rpc.log("state.floatValue: " + getState().floatValue); rpc.log("state.floatObjectValue: " + getState().floatObjectValue); - rpc.log("state.floatArray: " + getState().floatArray); + rpc.log("state.floatArray: " + Arrays.toString(getState().floatArray)); rpc.log("state.doubleValue: " + getState().doubleValue); rpc.log("state.doubleObjectValue: " + getState().doubleObjectValue); - rpc.log("state.doubleArray: " + getState().doubleArray); + rpc.log("state.doubleArray: " + Arrays.toString(getState().doubleArray)); /* * TODO public double doubleValue; public Double DoubleValue; public diff --git a/uitest/src/com/vaadin/tests/widgetset/client/csrf/CsrfButtonConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/csrf/CsrfButtonConnector.java new file mode 100644 index 0000000000..cf24ed6921 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/csrf/CsrfButtonConnector.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.client.csrf; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.google.gwt.core.shared.GWT; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.ui.VButton; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.client.MockApplicationConnection; +import com.vaadin.tests.widgetset.server.csrf.CsrfButton; + +/** + * Dummy connector to test our CSRF bug. See #14111. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +@Connect(CsrfButton.class) +public class CsrfButtonConnector extends AbstractComponentConnector { + + static Logger logger = Logger + .getLogger(CsrfButtonConnector.class.getName()); + static { + logger.setLevel(Level.ALL); + } + + @Override + public VButton getWidget() { + return (VButton) super.getWidget(); + } + + @Override + protected VButton createWidget() { + return GWT.create(VButton.class); + } + + public final static String ID = "CsrfButton"; + + @Override + public void init() { + super.init(); + + getWidget().getElement().setId(ID); + getWidget().setText(csrfTokenInfo()); + getWidget().addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + getWidget().setText(csrfTokenInfo()); + } + }); + } + + private String csrfTokenInfo() { + return getMockConnection().getCsrfToken() + ", " + + getMockConnection().getLastCsrfTokenReceiver() + ", " + + getMockConnection().getLastCsrfTokenSent(); + } + + private MockApplicationConnection getMockConnection() { + return (MockApplicationConnection) getConnection(); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java new file mode 100644 index 0000000000..b9037208f9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaConnector.java @@ -0,0 +1,15 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.client.ui.textarea.TextAreaConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.ExtraSuperTextArea; + +@Connect(ExtraSuperTextArea.class) +public class ExtraSuperTextAreaConnector extends TextAreaConnector { + + // @DelegateToWidget will not work with overridden state + @Override + public ExtraSuperTextAreaState getState() { + return (ExtraSuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java new file mode 100644 index 0000000000..44456b27ba --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/ExtraSuperTextAreaState.java @@ -0,0 +1,7 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.shared.ui.textarea.TextAreaState; + +public class ExtraSuperTextAreaState extends TextAreaState { + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java new file mode 100644 index 0000000000..fda1fc6f0a --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaConnector.java @@ -0,0 +1,19 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.client.ui.textarea.TextAreaConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.SuperTextArea; + +/** + * @author artamonov + * @version $Id$ + */ +@Connect(SuperTextArea.class) +public class SuperTextAreaConnector extends TextAreaConnector { + + // @DelegateToWidget will not work with overridden state + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java new file mode 100644 index 0000000000..005075429c --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/superText/SuperTextAreaState.java @@ -0,0 +1,11 @@ +package com.vaadin.tests.widgetset.client.superText; + +import com.vaadin.shared.ui.textarea.TextAreaState; + +/** + * @author artamonov + * @version $Id$ + */ +public class SuperTextAreaState extends TextAreaState { + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java b/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java new file mode 100644 index 0000000000..b741c099b5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/ExtraSuperTextArea.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.superText.SuperTextAreaState; +import com.vaadin.ui.TextArea; + +/** + * @author artamonov + * @version $Id$ + */ +public class ExtraSuperTextArea extends TextArea { + + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java new file mode 100644 index 0000000000..aadabb3fcc --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendants.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.ui.TextArea; + +/** + * UI for testing that @DelegateToWidget works on derived widget states. + * + * @since + * @author Vaadin Ltd + */ +@Widgetset(TestingWidgetSet.NAME) +public class OverriddenDecendants extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + TextArea normalTextArea = new TextArea(); + normalTextArea.setRows(10); + normalTextArea.setWordwrap(true); + + getLayout().addComponent(normalTextArea); + + // @DelegateToWidget will not work with overridden state in connector + SuperTextArea superTextArea = new SuperTextArea(); + superTextArea.setRows(10); + superTextArea.setWordwrap(true); + + getLayout().addComponent(superTextArea); + + // @DelegateToWidget will not work with overridden state in connector + ExtraSuperTextArea extraSuperTextArea = new ExtraSuperTextArea(); + extraSuperTextArea.setRows(10); + extraSuperTextArea.setWordwrap(true); + + getLayout().addComponent(extraSuperTextArea); + } + + @Override + protected String getTestDescription() { + return "@DelegateToWidget does not work for widget descendants with overridden getState"; + } + + @Override + protected Integer getTicketNumber() { + return 14059; + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java new file mode 100644 index 0000000000..aa29284010 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/OverriddenDecendantsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.elements.TextAreaElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Class for unit testing that @DelegateToWidget works on derived widget states. + * + * @since + * @author Vaadin Ltd + */ +public class OverriddenDecendantsTest extends MultiBrowserTest { + + @Test + public void allExtendingFieldsShouldGetRowsFromTextAreaStateAnnotation() + throws InterruptedException { + openTestURL(); + + List<TextAreaElement> textAreas = $(TextAreaElement.class).all(); + + assertEquals("Did not contain all 3 text areas", 3, textAreas.size()); + + for (TextAreaElement area : textAreas) { + assertEquals("Text area was missing rows", "10", + area.getAttribute("rows")); + } + + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java b/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java new file mode 100644 index 0000000000..6e73915e44 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/SuperTextArea.java @@ -0,0 +1,16 @@ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.superText.SuperTextAreaState; +import com.vaadin.ui.TextArea; + +/** + * @author artamonov + * @version $Id$ + */ +public class SuperTextArea extends TextArea { + + @Override + public SuperTextAreaState getState() { + return (SuperTextAreaState) super.getState(); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/CsrfButton.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/CsrfButton.java new file mode 100644 index 0000000000..567127927d --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/CsrfButton.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf; + +import com.vaadin.ui.AbstractComponent; + +/** + * Dummy client connector to link with the client functionality if the + * CsrfToken. + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class CsrfButton extends AbstractComponent { + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUI.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUI.java new file mode 100644 index 0000000000..f8f1754385 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUI.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.server.csrf.CsrfButton; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; + +/** + * Abstract UI to test the CSRF token issue as reported in (#14111) + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +@Widgetset(TestingWidgetSet.NAME) +public abstract class AbstractCsrfTokenUI extends AbstractTestUI { + + public static final String PRESS_ID = "PressMe"; + + @Override + protected void setup(VaadinRequest request) { + + addComponent(new Label("The button's text is the client token:")); + addComponent(new CsrfButton()); + addComponent(new Label("This one is from the server")); + addComponent(new Label(getSession().getCsrfToken())); + Button pressMe = new Button("Click me to send a request"); + pressMe.setId(PRESS_ID); + addComponent(pressMe); + } + + @Override + protected String getTestDescription() { + return "Remove csrfToken from the request if security protection is disabled."; + } + + @Override + protected Integer getTicketNumber() { + return 14111; + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUITest.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUITest.java new file mode 100644 index 0000000000..614eaa063e --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/AbstractCsrfTokenUITest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.widgetset.client.csrf.CsrfButtonConnector; + +public abstract class AbstractCsrfTokenUITest extends MultiBrowserTest { + + static final Logger LOGGER = Logger.getLogger(AbstractCsrfTokenUITest.class + .getName()); + + @Test + public void testTokens() { + openTestURL(); + + final By debugButton = By.id(CsrfButtonConnector.ID); + + final String debugMessage1 = getDriver().findElement(debugButton) + .getText(); + + getDriver().findElement(By.id(CsrfTokenDisabled.PRESS_ID)).click(); + + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + getDriver().findElement(debugButton).click(); + String debugMessage2 = input.findElement(debugButton).getText(); + + LOGGER.log(Level.INFO, "1: " + debugMessage1); + LOGGER.log(Level.INFO, "2: " + debugMessage2); + + if (!debugMessage1.equals(debugMessage2)) { + + compareMessage(split(debugMessage1), split(debugMessage2)); + + LOGGER.log(Level.INFO, "DONE"); + + return true; + + } else { + return false; + } + } + }); + } + + private TokenGroup split(String debugMessage) { + StringTokenizer tokenizer = new StringTokenizer(debugMessage, ", \""); + + return new TokenGroup(tokenizer.nextToken(), tokenizer.nextToken(), + tokenizer.nextToken()); + } + + /* + * Just implement this. + */ + protected abstract boolean compareMessage(TokenGroup tokenGroup1, + TokenGroup tokenGroup2); + + boolean isNullOrUndefined(String value) { + return isNull(value) || isUndefined(value); + } + + boolean isUndefined(String value) { + return value.equals("undefined"); + } + + boolean isNull(String value) { + return value.equals("null"); + } + + /* + * Wrapps all tokens from the client app. + */ + static class TokenGroup { + + public final String clientToken; + + public final String tokenReceivedFromServer; + + public final String tokenSentToServer; + + public TokenGroup(String clientToken, String tokenReceivedFromServer, + String tokenSentToServer) { + this.clientToken = clientToken; + this.tokenReceivedFromServer = tokenReceivedFromServer; + this.tokenSentToServer = tokenSentToServer; + } + + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabled.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabled.java new file mode 100644 index 0000000000..6283285b40 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabled.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +import com.vaadin.launcher.CustomDeploymentConfiguration; +import com.vaadin.launcher.CustomDeploymentConfiguration.Conf; + +/** + * When the disable-xsrf-protection is true csrfToken is not present anymore + * with the requests.<br/> + * This is useful mostly when the client is not Vaadin and so it will not push + * the parameter anyway. So now the server knows how to deal the issue if the + * csrfToken is not present. + * + * @since + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +@CustomDeploymentConfiguration({ @Conf(name = "disable-xsrf-protection", value = "true") }) +public class CsrfTokenDisabled extends AbstractCsrfTokenUI { + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabledTest.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabledTest.java new file mode 100644 index 0000000000..504425fead --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenDisabledTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +import com.vaadin.shared.ApplicationConstants; + +/** + * Test the CSRF Token issue. + * + * @since + * @author Vaadin Ltd + */ +public class CsrfTokenDisabledTest extends AbstractCsrfTokenUITest { + + @Override + protected boolean compareMessage(TokenGroup tokenGroup1, + TokenGroup tokenGroup2) { + + return tokenGroup1.clientToken + .equals(ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE) + && isUndefined(tokenGroup1.tokenReceivedFromServer) + && isUndefined(tokenGroup1.tokenSentToServer) + && tokenGroup2.clientToken + .equals(ApplicationConstants.CSRF_TOKEN_DEFAULT_VALUE) + && isUndefined(tokenGroup2.tokenReceivedFromServer) + // This is it actually, no token sent to the server. + && isNull(tokenGroup2.tokenSentToServer); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabled.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabled.java new file mode 100644 index 0000000000..cd02c6da77 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabled.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +import com.vaadin.launcher.CustomDeploymentConfiguration; +import com.vaadin.launcher.CustomDeploymentConfiguration.Conf; + +@SuppressWarnings("serial") +@CustomDeploymentConfiguration({ @Conf(name = "disable-xsrf-protection", value = "false") }) +public class CsrfTokenEnabled extends AbstractCsrfTokenUI { + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabledTest.java b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabledTest.java new file mode 100644 index 0000000000..1d51f1c372 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/csrf/ui/CsrfTokenEnabledTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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 + * + * http://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. + */ +package com.vaadin.tests.widgetset.server.csrf.ui; + +/** + * Test the CSRF Token issue. + * + * @since + * @author Vaadin Ltd + */ +public class CsrfTokenEnabledTest extends AbstractCsrfTokenUITest { + + @Override + protected boolean compareMessage(TokenGroup tokenGroup1, + TokenGroup tokenGroup2) { + + return tokenGroup1.clientToken.equals(tokenGroup2.clientToken) + // Valid token received and set on the client + && tokenGroup1.clientToken + .equals(tokenGroup1.tokenReceivedFromServer) + // No token sent yet to the server. + && isUndefined(tokenGroup1.tokenSentToServer) + // Token is sent to the server. + && tokenGroup2.clientToken + .equals(tokenGroup2.tokenSentToServer) + // And no more token received from the server. + && isUndefined(tokenGroup2.tokenReceivedFromServer); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java index d27884a13a..76d884d2c7 100644 --- a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java +++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java @@ -36,7 +36,7 @@ public class GwtRpcTest extends MultiBrowserTest { By label = By.id(GwtRpcButtonConnector.SUCCESS_LABEL_ID); - waitForElementToBePresent(label); + waitForElementVisible(label); getDriver().findElement(label); } diff --git a/uitest/test.xml b/uitest/test.xml index 57f61d67fa..2ee655ecf6 100644 --- a/uitest/test.xml +++ b/uitest/test.xml @@ -7,7 +7,7 @@ <!-- Configuration --> <!-- ================================================================== --> <!-- Browsers to use for testing --> - <property name="browsers-windows" value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-safari5,winxp-googlechrome21,winxp-opera12" /> + <property name="browsers-windows" value="winxp-ie8,win7-ie9,win7-ie10,winxp-firefox17-esr,winxp-googlechrome21" /> <property name="browsers-linux" value="linux-firefox3,linux-opera10,linux-googlechrome8" /> <property name="browsers-mac" value="osx-firefox3,osx-opera10,osx-googlechrome8,osx-safari4,osx-safari5" /> |