From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 2BF833851C36; Tue, 26 May 2020 08:20:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2BF833851C36 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: tzcode resync: details X-Act-Checkin: newlib-cygwin X-Git-Author: Mark Geisert X-Git-Refname: refs/heads/master X-Git-Oldrev: 2452e0b806c547a7a034d32fb6fae5b1c1ca810d X-Git-Newrev: 63ff2b84ff399fa64da6653ddb1238a887b1abad Message-Id: <20200526082034.2BF833851C36@sourceware.org> Date: Tue, 26 May 2020 08:20:34 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 26 May 2020 08:20:34 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=63ff2b84ff399fa64da6653ddb1238a887b1abad commit 63ff2b84ff399fa64da6653ddb1238a887b1abad Author: Mark Geisert Date: Fri May 22 02:32:53 2020 -0700 Cygwin: tzcode resync: details Add tz_posixrules.h with data generated from most recent Cygwin tzdata package. Establish localtime.cc as primarily a wrapper around a patched copy of localtime.c. See README for more information. Diff: --- winsup/cygwin/tzcode/README | 37 ++++++ winsup/cygwin/tzcode/localtime.c.patch | 59 +++++++++ winsup/cygwin/tzcode/localtime.cc | 159 +++++++++++++++++++++++ winsup/cygwin/tzcode/tz_posixrules.h | 231 +++++++++++++++++++++++++++++++++ 4 files changed, 486 insertions(+) diff --git a/winsup/cygwin/tzcode/README b/winsup/cygwin/tzcode/README new file mode 100644 index 000000000..b1a811e22 --- /dev/null +++ b/winsup/cygwin/tzcode/README @@ -0,0 +1,37 @@ +/* + How the code in this directory is supposed to work... + 2020/05/22 Mark Geisert + + localtime.cc is the Cygwin-specific module that is compiled into + the Cygwin DLL when the latter is built. It's just a wrapper that + #defines a bunch of stuff then #includes localtime.c. + + localtime.c, at any point in time, is a reasonably recent version + of /src/lib/libc/time/localtime.c from NetBSD. The same goes for + private.h and tzfile.h. An empty namespace.h suffices for Cygwin. + + The idea is that in the future, one just needs to bring over newer + versions of localtime.c, private.h, and/or tzfile.h from NetBSD as + they become available. + + With luck, you can drop those files into this directory and they + can be immediately used to build a newer Cygwin DLL that has the + newer NetBSD functionality. Without luck, you'll have to tweak the + wrapper localtime.cc. In the worst case, some other strategy will + need to be figured out, such as manually pulling out the parts of + the NetBSD code Cygwin needs to build a stand-alone localtime.cc. + + Re tz_posixrules.h: The data elements can be generated from + /usr/share/zoneinfo/posixrules in any version of Cygwin's tzdata + package. Instructions are in the comment leading tz_posixrules.h. + + Addendum: + Implementation of the strategy above has uncovered a small number + of NetBSD-isms in localtime.c that cannot be worked around with + preprocessor tricks. So there is another file localtime.c.patched + that holds just these adjustments for Cygwin, and it's this file + that localtime.cc #includes. localtime.c.patched is generated by + winsup/cygwin/Makefile[.in] operating with localtime.c.patch. + + ..mark +*/ diff --git a/winsup/cygwin/tzcode/localtime.c.patch b/winsup/cygwin/tzcode/localtime.c.patch new file mode 100644 index 000000000..e19a2cd02 --- /dev/null +++ b/winsup/cygwin/tzcode/localtime.c.patch @@ -0,0 +1,59 @@ +--- localtime.c 2020-05-16 21:54:00.533111800 -0700 ++++ localtime.c.patched 2020-05-22 00:03:30.826646000 -0700 +@@ -413,7 +413,7 @@ + }; + + /* TZDIR with a trailing '/' rather than a trailing '\0'. */ +-static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; ++static char const tzdirslash[sizeof TZDIR + 1] = TZDIR "/"; + + /* Local storage needed for 'tzloadbody'. */ + union local_storage { +@@ -473,7 +473,7 @@ + would pull in stdio (and would fail if the + resulting string length exceeded INT_MAX!). */ + memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); +- strcpy(lsp->fullname + sizeof tzdirslash, name); ++ strcpy(lsp->fullname + sizeof tzdirslash - 1, name); + + /* Set doaccess if NAME contains a ".." file name + component, as such a name could read a file outside +@@ -488,11 +488,11 @@ + name = lsp->fullname; + } + if (doaccess && access(name, R_OK) != 0) +- return errno; ++ goto trydefrules; + + fid = open(name, OPEN_MODE); + if (fid < 0) +- return errno; ++ goto trydefrules; + nread = read(fid, up->buf, sizeof up->buf); + if (nread < (ssize_t)tzheadsize) { + int err = nread < 0 ? errno : EINVAL; +@@ -501,6 +501,15 @@ + } + if (close(fid) < 0) + return errno; ++ if (0) { ++trydefrules: ++ const char *base = strrchr(name, '/'); ++ base = base ? base + 1 : name; ++ if (strcmp(base, TZDEFRULES)) ++ return errno; ++ nread = sizeof _posixrules_data; ++ memcpy(up->buf, _posixrules_data, nread); ++ } + for (stored = 4; stored <= 8; stored *= 2) { + int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); + int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); +@@ -1417,6 +1426,8 @@ + tzsetlcl(char const *name) + { + struct state *sp = __lclptr; ++ if (! name) ++ name = tzgetwintzi(__UNCONST(wildabbr), (char *) alloca (512)); + int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; + if (lcl < 0 ? lcl_is_set < 0 + : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) diff --git a/winsup/cygwin/tzcode/localtime.cc b/winsup/cygwin/tzcode/localtime.cc new file mode 100644 index 000000000..c903bf3b9 --- /dev/null +++ b/winsup/cygwin/tzcode/localtime.cc @@ -0,0 +1,159 @@ +/* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file. + +This file is part of Cygwin. + +This software is a copyrighted work licensed under the terms of the +Cygwin license. Please consult the file "CYGWIN_LICENSE" for +details. */ + +#include "../winsup.h" +#include "../sync.h" +#include "../include/cygwin/version.h" +#include "tz_posixrules.h" + +static NO_COPY muto tzset_guard; + +// Convert these NetBSD rwlock ops into Cygwin muto ops +#define rwlock_wrlock(X) tzset_guard.init("tzset_guard")->acquire() +#define rwlock_unlock(X) tzset_guard.release() + +// Set these NetBSD-related option #defines appropriately for Cygwin +//#define STD_INSPIRED // early-include private.h below does this +#define lint +#define HAVE_POSIX_DECLS 0 +#define USG_COMPAT 1 +#define NO_ERROR_IN_DST_GAP +#define state __state + +// Turn a specific known kind of const parameter into non-const +#define __UNCONST(X) ((char *) (X)) + +// Turn off these NetBSD audit-related definitions +#define __aconst +#define _DIAGASSERT(X) + +// Supply this Cygwin-specific function in advance of its use in localtime.c +static char * +tzgetwintzi (char *wildabbr, char *outbuf) +{ + TIME_ZONE_INFORMATION tzi; + char *cp, *dst; + wchar_t *wsrc; + div_t d; + + GetTimeZoneInformation (&tzi); + dst = cp = outbuf; + for (wsrc = tzi.StandardName; *wsrc; wsrc++) + if (*wsrc >= L'A' && *wsrc <= L'Z') + *dst++ = *wsrc; + if ((dst - cp) < 3) + { + /* In non-english Windows, converted tz.StandardName + may not contain a valid standard timezone name. */ + strcpy (cp, wildabbr); + cp += strlen (wildabbr); + } + else + cp = dst; + d = div (tzi.Bias + tzi.StandardBias, 60); + __small_sprintf (cp, "%d", d.quot); + if (d.rem) + __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem)); + if (tzi.StandardDate.wMonth) + { + cp = strchr (cp, 0); + dst = cp; + for (wsrc = tzi.DaylightName; *wsrc; wsrc++) + if (*wsrc >= L'A' && *wsrc <= L'Z') + *dst++ = *wsrc; + if ((dst - cp) < 3) + { + /* In non-english Windows, converted tz.DaylightName + may not contain a valid daylight timezone name. */ + strcpy (cp, wildabbr); + cp += strlen (wildabbr); + } + else + cp = dst; + d = div (tzi.Bias + tzi.DaylightBias, 60); + __small_sprintf (cp, "%d", d.quot); + if (d.rem) + __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem)); + cp = strchr (cp, 0); + __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d", + tzi.DaylightDate.wMonth, + tzi.DaylightDate.wDay, + tzi.DaylightDate.wDayOfWeek, + tzi.DaylightDate.wHour); + if (tzi.DaylightDate.wMinute || tzi.DaylightDate.wSecond) + __small_sprintf (cp = strchr (cp, 0), ":%d", + tzi.DaylightDate.wMinute); + if (tzi.DaylightDate.wSecond) + __small_sprintf (cp = strchr (cp, 0), ":%d", + tzi.DaylightDate.wSecond); + cp = strchr (cp, 0); + __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d", + tzi.StandardDate.wMonth, + tzi.StandardDate.wDay, + tzi.StandardDate.wDayOfWeek, + tzi.StandardDate.wHour); + if (tzi.StandardDate.wMinute || tzi.StandardDate.wSecond) + __small_sprintf (cp = strchr (cp, 0), ":%d", + tzi.StandardDate.wMinute); + if (tzi.StandardDate.wSecond) + __small_sprintf (cp = strchr (cp, 0), ":%d", + tzi.StandardDate.wSecond); + } + /* __small_printf ("TZ deduced as `%s'\n", outbuf); */ + return outbuf; +} + +// Get ready to wrap NetBSD's localtime.c +#ifdef __cplusplus +extern "C" { +#endif + +// Pull these in early to catch any small issues before the real test +#include "private.h" +#include "tzfile.h" + +/* Some NetBSD differences were too difficult to work around.. + so #include a patched copy of localtime.c rather than the NetBSD original. + Here is a list of the patches... + (1) fix an erroneous decl of tzdirslash size (flagged by g++) + (2) add conditional call to Cygwin's tzgetwintzi() from tzsetlcl() + (3) add Cygwin's historical "posixrules" support to tzloadbody() +*/ +#include "localtime.c.patched" + +#ifdef __cplusplus +} +#endif + +// Don't forget these Cygwin-specific additions from this point to EOF +EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked) + +extern "C" long +__cygwin_gettzoffset (const struct tm *tmp) +{ +#ifdef TM_GMTOFF + if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS) + return tmp->TM_GMTOFF; +#endif /* defined TM_GMTOFF */ + __tzinfo_type *tz = __gettzinfo (); + /* The sign of this is exactly opposite the envvar TZ. We + could directly use the global _timezone for tm_isdst==0, + but have to use __tzrule for daylight savings. */ + long offset = -tz->__tzrule[tmp->tm_isdst > 0].offset; + return offset; +} + +extern "C" const char * +__cygwin_gettzname (const struct tm *tmp) +{ +#ifdef TM_ZONE + if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS) + return tmp->TM_ZONE; +#endif + return _tzname[tmp->tm_isdst > 0]; +} diff --git a/winsup/cygwin/tzcode/tz_posixrules.h b/winsup/cygwin/tzcode/tz_posixrules.h new file mode 100644 index 000000000..ebfcd065a --- /dev/null +++ b/winsup/cygwin/tzcode/tz_posixrules.h @@ -0,0 +1,231 @@ +/* tz_posixrules.h + * + * The data elements were generated with... + * od -vt u1 -A n /usr/share/zoneinfo/posixrules | + * sed 's/$/,/;s/^ //;s/[0-9] /&,/g;s/ ,/, /g' > elements_file + * + * The source posixrules file is from the Cygwin tzdata 2020a-1 package. + */ +static NO_COPY unsigned char _posixrules_data[] = { + 84, 90, 105, 102, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 236, 0, 0, 0, 5, 0, 0, 0, 20, 128, 0, 0, 0, +158, 166, 30, 112, 159, 186, 235, 96, 160, 134, 0, 112, 161, 154, 205, 96, +162, 101, 226, 112, 163, 131, 233, 224, 164, 106, 174, 112, 165, 53, 167, 96, +166, 83, 202, 240, 167, 21, 137, 96, 168, 51, 172, 240, 168, 254, 165, 224, +170, 19, 142, 240, 170, 222, 135, 224, 171, 243, 112, 240, 172, 190, 105, 224, +173, 211, 82, 240, 174, 158, 75, 224, 175, 179, 52, 240, 176, 126, 45, 224, +177, 156, 81, 112, 178, 103, 74, 96, 179, 124, 51, 112, 180, 71, 44, 96, +181, 92, 21, 112, 182, 39, 14, 96, 183, 59, 247, 112, 184, 6, 240, 96, +185, 27, 217, 112, 185, 230, 210, 96, 187, 4, 245, 240, 187, 198, 180, 96, +188, 228, 215, 240, 189, 175, 208, 224, 190, 196, 185, 240, 191, 143, 178, 224, +192, 164, 155, 240, 193, 111, 148, 224, 194, 132, 125, 240, 195, 79, 118, 224, +196, 100, 95, 240, 197, 47, 88, 224, 198, 77, 124, 112, 199, 15, 58, 224, +200, 45, 94, 112, 200, 248, 87, 96, 202, 13, 64, 112, 202, 216, 57, 96, +203, 136, 240, 112, 210, 35, 244, 112, 210, 96, 251, 224, 211, 117, 228, 240, +212, 64, 221, 224, 213, 85, 198, 240, 214, 32, 191, 224, 215, 53, 168, 240, +216, 0, 161, 224, 217, 21, 138, 240, 217, 224, 131, 224, 218, 254, 167, 112, +219, 192, 101, 224, 220, 222, 137, 112, 221, 169, 130, 96, 222, 190, 107, 112, +223, 137, 100, 96, 224, 158, 77, 112, 225, 105, 70, 96, 226, 126, 47, 112, +227, 73, 40, 96, 228, 94, 17, 112, 229, 87, 46, 224, 230, 71, 45, 240, +231, 55, 16, 224, 232, 39, 15, 240, 233, 22, 242, 224, 234, 6, 241, 240, +234, 246, 212, 224, 235, 230, 211, 240, 236, 214, 182, 224, 237, 198, 181, 240, +238, 191, 211, 96, 239, 175, 210, 112, 240, 159, 181, 96, 241, 143, 180, 112, +242, 127, 151, 96, 243, 111, 150, 112, 244, 95, 121, 96, 245, 79, 120, 112, +246, 63, 91, 96, 247, 47, 90, 112, 248, 40, 119, 224, 249, 15, 60, 112, +250, 8, 89, 224, 250, 248, 88, 240, 251, 232, 59, 224, 252, 216, 58, 240, +253, 200, 29, 224, 254, 184, 28, 240, 255, 167, 255, 224, 0, 151, 254, 240, + 1, 135, 225, 224, 2, 119, 224, 240, 3, 112, 254, 96, 4, 96, 253, 112, + 5, 80, 224, 96, 6, 64, 223, 112, 7, 48, 194, 96, 7, 141, 25, 112, + 9, 16, 164, 96, 9, 173, 148, 240, 10, 240, 134, 96, 11, 224, 133, 112, + 12, 217, 162, 224, 13, 192, 103, 112, 14, 185, 132, 224, 15, 169, 131, 240, + 16, 153, 102, 224, 17, 137, 101, 240, 18, 121, 72, 224, 19, 105, 71, 240, + 20, 89, 42, 224, 21, 73, 41, 240, 22, 57, 12, 224, 23, 41, 11, 240, + 24, 34, 41, 96, 25, 8, 237, 240, 26, 2, 11, 96, 26, 242, 10, 112, + 27, 225, 237, 96, 28, 209, 236, 112, 29, 193, 207, 96, 30, 177, 206, 112, + 31, 161, 177, 96, 32, 118, 0, 240, 33, 129, 147, 96, 34, 85, 226, 240, + 35, 106, 175, 224, 36, 53, 196, 240, 37, 74, 145, 224, 38, 21, 166, 240, + 39, 42, 115, 224, 39, 254, 195, 112, 41, 10, 85, 224, 41, 222, 165, 112, + 42, 234, 55, 224, 43, 190, 135, 112, 44, 211, 84, 96, 45, 158, 105, 112, + 46, 179, 54, 96, 47, 126, 75, 112, 48, 147, 24, 96, 49, 103, 103, 240, + 50, 114, 250, 96, 51, 71, 73, 240, 52, 82, 220, 96, 53, 39, 43, 240, + 54, 50, 190, 96, 55, 7, 13, 240, 56, 27, 218, 224, 56, 230, 239, 240, + 57, 251, 188, 224, 58, 198, 209, 240, 59, 219, 158, 224, 60, 175, 238, 112, + 61, 187, 128, 224, 62, 143, 208, 112, 63, 155, 98, 224, 64, 111, 178, 112, + 65, 132, 127, 96, 66, 79, 148, 112, 67, 100, 97, 96, 68, 47, 118, 112, + 69, 68, 67, 96, 69, 243, 168, 240, 71, 45, 95, 224, 71, 211, 138, 240, + 73, 13, 65, 224, 73, 179, 108, 240, 74, 237, 35, 224, 75, 156, 137, 112, + 76, 214, 64, 96, 77, 124, 107, 112, 78, 182, 34, 96, 79, 92, 77, 112, + 80, 150, 4, 96, 81, 60, 47, 112, 82, 117, 230, 96, 83, 28, 17, 112, + 84, 85, 200, 96, 84, 251, 243, 112, 86, 53, 170, 96, 86, 229, 15, 240, + 88, 30, 198, 224, 88, 196, 241, 240, 89, 254, 168, 224, 90, 164, 211, 240, + 91, 222, 138, 224, 92, 132, 181, 240, 93, 190, 108, 224, 94, 100, 151, 240, + 95, 158, 78, 224, 96, 77, 180, 112, 97, 135, 107, 96, 98, 45, 150, 112, + 99, 103, 77, 96, 100, 13, 120, 112, 101, 71, 47, 96, 101, 237, 90, 112, +103, 39, 17, 96, 103, 205, 60, 112, 105, 6, 243, 96, 105, 173, 30, 112, +106, 230, 213, 96, 107, 150, 58, 240, 108, 207, 241, 224, 109, 118, 28, 240, +110, 175, 211, 224, 111, 85, 254, 240, 112, 143, 181, 224, 113, 53, 224, 240, +114, 111, 151, 224, 115, 21, 194, 240, 116, 79, 121, 224, 116, 254, 223, 112, +118, 56, 150, 96, 118, 222, 193, 112, 120, 24, 120, 96, 120, 190, 163, 112, +121, 248, 90, 96, 122, 158, 133, 112, 123, 216, 60, 96, 124, 126, 103, 112, +125, 184, 30, 96, 126, 94, 73, 112, 127, 152, 0, 96, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 255, 255, 186, 158, 0, 0, 255, 255, +199, 192, 1, 4, 255, 255, 185, 176, 0, 8, 255, 255, 199, 192, 1, 12, +255, 255, 199, 192, 1, 16, 76, 77, 84, 0, 69, 68, 84, 0, 69, 83, + 84, 0, 69, 87, 84, 0, 69, 80, 84, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 84, 90, 105, 102, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 5, 0, 0, 0, 20, +255, 255, 255, 255, 94, 3, 240, 144, 255, 255, 255, 255, 158, 166, 30, 112, +255, 255, 255, 255, 159, 186, 235, 96, 255, 255, 255, 255, 160, 134, 0, 112, +255, 255, 255, 255, 161, 154, 205, 96, 255, 255, 255, 255, 162, 101, 226, 112, +255, 255, 255, 255, 163, 131, 233, 224, 255, 255, 255, 255, 164, 106, 174, 112, +255, 255, 255, 255, 165, 53, 167, 96, 255, 255, 255, 255, 166, 83, 202, 240, +255, 255, 255, 255, 167, 21, 137, 96, 255, 255, 255, 255, 168, 51, 172, 240, +255, 255, 255, 255, 168, 254, 165, 224, 255, 255, 255, 255, 170, 19, 142, 240, +255, 255, 255, 255, 170, 222, 135, 224, 255, 255, 255, 255, 171, 243, 112, 240, +255, 255, 255, 255, 172, 190, 105, 224, 255, 255, 255, 255, 173, 211, 82, 240, +255, 255, 255, 255, 174, 158, 75, 224, 255, 255, 255, 255, 175, 179, 52, 240, +255, 255, 255, 255, 176, 126, 45, 224, 255, 255, 255, 255, 177, 156, 81, 112, +255, 255, 255, 255, 178, 103, 74, 96, 255, 255, 255, 255, 179, 124, 51, 112, +255, 255, 255, 255, 180, 71, 44, 96, 255, 255, 255, 255, 181, 92, 21, 112, +255, 255, 255, 255, 182, 39, 14, 96, 255, 255, 255, 255, 183, 59, 247, 112, +255, 255, 255, 255, 184, 6, 240, 96, 255, 255, 255, 255, 185, 27, 217, 112, +255, 255, 255, 255, 185, 230, 210, 96, 255, 255, 255, 255, 187, 4, 245, 240, +255, 255, 255, 255, 187, 198, 180, 96, 255, 255, 255, 255, 188, 228, 215, 240, +255, 255, 255, 255, 189, 175, 208, 224, 255, 255, 255, 255, 190, 196, 185, 240, +255, 255, 255, 255, 191, 143, 178, 224, 255, 255, 255, 255, 192, 164, 155, 240, +255, 255, 255, 255, 193, 111, 148, 224, 255, 255, 255, 255, 194, 132, 125, 240, +255, 255, 255, 255, 195, 79, 118, 224, 255, 255, 255, 255, 196, 100, 95, 240, +255, 255, 255, 255, 197, 47, 88, 224, 255, 255, 255, 255, 198, 77, 124, 112, +255, 255, 255, 255, 199, 15, 58, 224, 255, 255, 255, 255, 200, 45, 94, 112, +255, 255, 255, 255, 200, 248, 87, 96, 255, 255, 255, 255, 202, 13, 64, 112, +255, 255, 255, 255, 202, 216, 57, 96, 255, 255, 255, 255, 203, 136, 240, 112, +255, 255, 255, 255, 210, 35, 244, 112, 255, 255, 255, 255, 210, 96, 251, 224, +255, 255, 255, 255, 211, 117, 228, 240, 255, 255, 255, 255, 212, 64, 221, 224, +255, 255, 255, 255, 213, 85, 198, 240, 255, 255, 255, 255, 214, 32, 191, 224, +255, 255, 255, 255, 215, 53, 168, 240, 255, 255, 255, 255, 216, 0, 161, 224, +255, 255, 255, 255, 217, 21, 138, 240, 255, 255, 255, 255, 217, 224, 131, 224, +255, 255, 255, 255, 218, 254, 167, 112, 255, 255, 255, 255, 219, 192, 101, 224, +255, 255, 255, 255, 220, 222, 137, 112, 255, 255, 255, 255, 221, 169, 130, 96, +255, 255, 255, 255, 222, 190, 107, 112, 255, 255, 255, 255, 223, 137, 100, 96, +255, 255, 255, 255, 224, 158, 77, 112, 255, 255, 255, 255, 225, 105, 70, 96, +255, 255, 255, 255, 226, 126, 47, 112, 255, 255, 255, 255, 227, 73, 40, 96, +255, 255, 255, 255, 228, 94, 17, 112, 255, 255, 255, 255, 229, 87, 46, 224, +255, 255, 255, 255, 230, 71, 45, 240, 255, 255, 255, 255, 231, 55, 16, 224, +255, 255, 255, 255, 232, 39, 15, 240, 255, 255, 255, 255, 233, 22, 242, 224, +255, 255, 255, 255, 234, 6, 241, 240, 255, 255, 255, 255, 234, 246, 212, 224, +255, 255, 255, 255, 235, 230, 211, 240, 255, 255, 255, 255, 236, 214, 182, 224, +255, 255, 255, 255, 237, 198, 181, 240, 255, 255, 255, 255, 238, 191, 211, 96, +255, 255, 255, 255, 239, 175, 210, 112, 255, 255, 255, 255, 240, 159, 181, 96, +255, 255, 255, 255, 241, 143, 180, 112, 255, 255, 255, 255, 242, 127, 151, 96, +255, 255, 255, 255, 243, 111, 150, 112, 255, 255, 255, 255, 244, 95, 121, 96, +255, 255, 255, 255, 245, 79, 120, 112, 255, 255, 255, 255, 246, 63, 91, 96, +255, 255, 255, 255, 247, 47, 90, 112, 255, 255, 255, 255, 248, 40, 119, 224, +255, 255, 255, 255, 249, 15, 60, 112, 255, 255, 255, 255, 250, 8, 89, 224, +255, 255, 255, 255, 250, 248, 88, 240, 255, 255, 255, 255, 251, 232, 59, 224, +255, 255, 255, 255, 252, 216, 58, 240, 255, 255, 255, 255, 253, 200, 29, 224, +255, 255, 255, 255, 254, 184, 28, 240, 255, 255, 255, 255, 255, 167, 255, 224, + 0, 0, 0, 0, 0, 151, 254, 240, 0, 0, 0, 0, 1, 135, 225, 224, + 0, 0, 0, 0, 2, 119, 224, 240, 0, 0, 0, 0, 3, 112, 254, 96, + 0, 0, 0, 0, 4, 96, 253, 112, 0, 0, 0, 0, 5, 80, 224, 96, + 0, 0, 0, 0, 6, 64, 223, 112, 0, 0, 0, 0, 7, 48, 194, 96, + 0, 0, 0, 0, 7, 141, 25, 112, 0, 0, 0, 0, 9, 16, 164, 96, + 0, 0, 0, 0, 9, 173, 148, 240, 0, 0, 0, 0, 10, 240, 134, 96, + 0, 0, 0, 0, 11, 224, 133, 112, 0, 0, 0, 0, 12, 217, 162, 224, + 0, 0, 0, 0, 13, 192, 103, 112, 0, 0, 0, 0, 14, 185, 132, 224, + 0, 0, 0, 0, 15, 169, 131, 240, 0, 0, 0, 0, 16, 153, 102, 224, + 0, 0, 0, 0, 17, 137, 101, 240, 0, 0, 0, 0, 18, 121, 72, 224, + 0, 0, 0, 0, 19, 105, 71, 240, 0, 0, 0, 0, 20, 89, 42, 224, + 0, 0, 0, 0, 21, 73, 41, 240, 0, 0, 0, 0, 22, 57, 12, 224, + 0, 0, 0, 0, 23, 41, 11, 240, 0, 0, 0, 0, 24, 34, 41, 96, + 0, 0, 0, 0, 25, 8, 237, 240, 0, 0, 0, 0, 26, 2, 11, 96, + 0, 0, 0, 0, 26, 242, 10, 112, 0, 0, 0, 0, 27, 225, 237, 96, + 0, 0, 0, 0, 28, 209, 236, 112, 0, 0, 0, 0, 29, 193, 207, 96, + 0, 0, 0, 0, 30, 177, 206, 112, 0, 0, 0, 0, 31, 161, 177, 96, + 0, 0, 0, 0, 32, 118, 0, 240, 0, 0, 0, 0, 33, 129, 147, 96, + 0, 0, 0, 0, 34, 85, 226, 240, 0, 0, 0, 0, 35, 106, 175, 224, + 0, 0, 0, 0, 36, 53, 196, 240, 0, 0, 0, 0, 37, 74, 145, 224, + 0, 0, 0, 0, 38, 21, 166, 240, 0, 0, 0, 0, 39, 42, 115, 224, + 0, 0, 0, 0, 39, 254, 195, 112, 0, 0, 0, 0, 41, 10, 85, 224, + 0, 0, 0, 0, 41, 222, 165, 112, 0, 0, 0, 0, 42, 234, 55, 224, + 0, 0, 0, 0, 43, 190, 135, 112, 0, 0, 0, 0, 44, 211, 84, 96, + 0, 0, 0, 0, 45, 158, 105, 112, 0, 0, 0, 0, 46, 179, 54, 96, + 0, 0, 0, 0, 47, 126, 75, 112, 0, 0, 0, 0, 48, 147, 24, 96, + 0, 0, 0, 0, 49, 103, 103, 240, 0, 0, 0, 0, 50, 114, 250, 96, + 0, 0, 0, 0, 51, 71, 73, 240, 0, 0, 0, 0, 52, 82, 220, 96, + 0, 0, 0, 0, 53, 39, 43, 240, 0, 0, 0, 0, 54, 50, 190, 96, + 0, 0, 0, 0, 55, 7, 13, 240, 0, 0, 0, 0, 56, 27, 218, 224, + 0, 0, 0, 0, 56, 230, 239, 240, 0, 0, 0, 0, 57, 251, 188, 224, + 0, 0, 0, 0, 58, 198, 209, 240, 0, 0, 0, 0, 59, 219, 158, 224, + 0, 0, 0, 0, 60, 175, 238, 112, 0, 0, 0, 0, 61, 187, 128, 224, + 0, 0, 0, 0, 62, 143, 208, 112, 0, 0, 0, 0, 63, 155, 98, 224, + 0, 0, 0, 0, 64, 111, 178, 112, 0, 0, 0, 0, 65, 132, 127, 96, + 0, 0, 0, 0, 66, 79, 148, 112, 0, 0, 0, 0, 67, 100, 97, 96, + 0, 0, 0, 0, 68, 47, 118, 112, 0, 0, 0, 0, 69, 68, 67, 96, + 0, 0, 0, 0, 69, 243, 168, 240, 0, 0, 0, 0, 71, 45, 95, 224, + 0, 0, 0, 0, 71, 211, 138, 240, 0, 0, 0, 0, 73, 13, 65, 224, + 0, 0, 0, 0, 73, 179, 108, 240, 0, 0, 0, 0, 74, 237, 35, 224, + 0, 0, 0, 0, 75, 156, 137, 112, 0, 0, 0, 0, 76, 214, 64, 96, + 0, 0, 0, 0, 77, 124, 107, 112, 0, 0, 0, 0, 78, 182, 34, 96, + 0, 0, 0, 0, 79, 92, 77, 112, 0, 0, 0, 0, 80, 150, 4, 96, + 0, 0, 0, 0, 81, 60, 47, 112, 0, 0, 0, 0, 82, 117, 230, 96, + 0, 0, 0, 0, 83, 28, 17, 112, 0, 0, 0, 0, 84, 85, 200, 96, + 0, 0, 0, 0, 84, 251, 243, 112, 0, 0, 0, 0, 86, 53, 170, 96, + 0, 0, 0, 0, 86, 229, 15, 240, 0, 0, 0, 0, 88, 30, 198, 224, + 0, 0, 0, 0, 88, 196, 241, 240, 0, 0, 0, 0, 89, 254, 168, 224, + 0, 0, 0, 0, 90, 164, 211, 240, 0, 0, 0, 0, 91, 222, 138, 224, + 0, 0, 0, 0, 92, 132, 181, 240, 0, 0, 0, 0, 93, 190, 108, 224, + 0, 0, 0, 0, 94, 100, 151, 240, 0, 0, 0, 0, 95, 158, 78, 224, + 0, 0, 0, 0, 96, 77, 180, 112, 0, 0, 0, 0, 97, 135, 107, 96, + 0, 0, 0, 0, 98, 45, 150, 112, 0, 0, 0, 0, 99, 103, 77, 96, + 0, 0, 0, 0, 100, 13, 120, 112, 0, 0, 0, 0, 101, 71, 47, 96, + 0, 0, 0, 0, 101, 237, 90, 112, 0, 0, 0, 0, 103, 39, 17, 96, + 0, 0, 0, 0, 103, 205, 60, 112, 0, 0, 0, 0, 105, 6, 243, 96, + 0, 0, 0, 0, 105, 173, 30, 112, 0, 0, 0, 0, 106, 230, 213, 96, + 0, 0, 0, 0, 107, 150, 58, 240, 0, 0, 0, 0, 108, 207, 241, 224, + 0, 0, 0, 0, 109, 118, 28, 240, 0, 0, 0, 0, 110, 175, 211, 224, + 0, 0, 0, 0, 111, 85, 254, 240, 0, 0, 0, 0, 112, 143, 181, 224, + 0, 0, 0, 0, 113, 53, 224, 240, 0, 0, 0, 0, 114, 111, 151, 224, + 0, 0, 0, 0, 115, 21, 194, 240, 0, 0, 0, 0, 116, 79, 121, 224, + 0, 0, 0, 0, 116, 254, 223, 112, 0, 0, 0, 0, 118, 56, 150, 96, + 0, 0, 0, 0, 118, 222, 193, 112, 0, 0, 0, 0, 120, 24, 120, 96, + 0, 0, 0, 0, 120, 190, 163, 112, 0, 0, 0, 0, 121, 248, 90, 96, + 0, 0, 0, 0, 122, 158, 133, 112, 0, 0, 0, 0, 123, 216, 60, 96, + 0, 0, 0, 0, 124, 126, 103, 112, 0, 0, 0, 0, 125, 184, 30, 96, + 0, 0, 0, 0, 126, 94, 73, 112, 0, 0, 0, 0, 127, 152, 0, 96, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 3, 4, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 255, 255, 186, 158, + 0, 0, 255, 255, 199, 192, 1, 4, 255, 255, 185, 176, 0, 8, 255, 255, +199, 192, 1, 12, 255, 255, 199, 192, 1, 16, 76, 77, 84, 0, 69, 68, + 84, 0, 69, 83, 84, 0, 69, 87, 84, 0, 69, 80, 84, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 1, 10, 69, 83, 84, 53, 69, 68, 84, + 44, 77, 51, 46, 50, 46, 48, 44, 77, 49, 49, 46, 49, 46, 48, 10, +};