diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a8e93d0bee..b5b4c653cd 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -389,6 +389,25 @@ \sa fromUserInput() */ +/*! + \enum QUrl::AceProcessingOption + \since 6.3 + + The ACE processing options control the way URLs are transformed to and from + ASCII-Compatible Encoding. + + \value IgnoreIDNWhitelist Ignore the IDN whitelist when converting URLs + to Unicode. + \value AceTransitionalProcessing Use transitional processing described in UTS #46. + This allows better compatibility with IDNA 2003 + specification. + + The default is to use nontransitional processing and to allow non-ASCII + characters only inside URLs whose top-level domains are listed in the IDN whitelist. + + \sa toAce(), fromAce(), idnWhitelist() +*/ + /*! \fn QUrl::QUrl(QUrl &&other) @@ -1177,7 +1196,7 @@ inline void QUrlPrivate::appendHost(QString &appendTo, QUrl::FormattingOptions o // this is either an IPv4Address or a reg-name // if it is a reg-name, it is already stored in Unicode form if (options & QUrl::EncodeUnicode && !(options & 0x4000000)) - appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot); + appendTo += qt_ACE_do(host, ToAceOnly, AllowLeadingDot, {}); else appendTo += host; } @@ -1339,7 +1358,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl: // Unicode encoding (some non-ASCII characters case-fold to digits // when nameprepping is done) // - // The qt_ACE_do function below applies nameprepping and the STD3 check. + // The qt_ACE_do function below does IDNA normalization and the STD3 check. // That means a Unicode string may become an IPv4 address, but it cannot // produce a '[' or a '%'. @@ -1358,7 +1377,7 @@ inline bool QUrlPrivate::setHost(const QString &value, int from, int iend, QUrl: return setHost(s, 0, s.length(), QUrl::StrictMode); } - s = qt_ACE_do(QStringView(begin, len), NormalizeAce, ForbidLeadingDot); + s = qt_ACE_do(value.mid(from, iend - from), NormalizeAce, ForbidLeadingDot, {}); if (s.isEmpty()) { setError(InvalidRegNameError, value); return false; @@ -3013,50 +3032,72 @@ QByteArray QUrl::toPercentEncoding(const QString &input, const QByteArray &exclu } /*! - \since 4.2 + \since 6.3 Returns the Unicode form of the given domain name \a domain, which is encoded in the ASCII Compatible Encoding (ACE). + The output can be customized by passing flags with \a options. The result of this function is considered equivalent to \a domain. If the value in \a domain cannot be encoded, it will be converted to QString and returned. - The ASCII Compatible Encoding (ACE) is defined by RFC 3490, RFC 3491 - and RFC 3492. It is part of the Internationalizing Domain Names in - Applications (IDNA) specification, which allows for domain names - (like \c "example.com") to be written using international - characters. + The ASCII-Compatible Encoding (ACE) is defined by RFC 3490, RFC 3491 + and RFC 3492 and updated by the Unicode Technical Standard #46. It is part + of the Internationalizing Domain Names in Applications (IDNA) specification, + which allows for domain names (like \c "example.com") to be written using + non-US-ASCII characters. +*/ +QString QUrl::fromAce(const QByteArray &domain, QUrl::AceProcessingOptions options) +{ + return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce, + ForbidLeadingDot /*FIXME: make configurable*/, options); +} + +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +/*! + \since 4.2 + \overload */ QString QUrl::fromAce(const QByteArray &domain) { - QVarLengthArray buffer; - buffer.resize(domain.size()); - qt_from_latin1(buffer.data(), domain.data(), domain.size()); - return qt_ACE_do(QStringView{buffer.data(), buffer.size()}, - NormalizeAce, ForbidLeadingDot /*FIXME: make configurable*/); + return fromAce(domain, {}); } +#endif /*! - \since 4.2 + \since 6.3 Returns the ASCII Compatible Encoding of the given domain name \a domain. + The output can be customized by passing flags with \a options. The result of this function is considered equivalent to \a domain. The ASCII-Compatible Encoding (ACE) is defined by RFC 3490, RFC 3491 - and RFC 3492. It is part of the Internationalizing Domain Names in - Applications (IDNA) specification, which allows for domain names - (like \c "example.com") to be written using international - characters. + and RFC 3492 and updated by the Unicode Technical Standard #46. It is part + of the Internationalizing Domain Names in Applications (IDNA) specification, + which allows for domain names (like \c "example.com") to be written using + non-US-ASCII characters. This function returns an empty QByteArray if \a domain is not a valid hostname. Note, in particular, that IPv6 literals are not valid domain names. */ +QByteArray QUrl::toAce(const QString &domain, AceProcessingOptions options) +{ + return qt_ACE_do(domain, ToAceOnly, ForbidLeadingDot /*FIXME: make configurable*/, options) + .toLatin1(); +} + +#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) +/*! + \since 4.2 + \overload +*/ QByteArray QUrl::toAce(const QString &domain) { - return qt_ACE_do(domain, ToAceOnly, ForbidLeadingDot /*FIXME: make configurable*/).toLatin1(); + return toAce(domain, {}); } +#endif /*! \internal diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index dffe81e885..90587f39fe 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -281,8 +281,22 @@ public: NSURL *toNSURL() const Q_DECL_NS_RETURNS_AUTORELEASED; #endif + enum AceProcessingOption : unsigned int { + IgnoreIDNWhitelist = 0x1, + AceTransitionalProcessing = 0x2, + }; + Q_DECLARE_FLAGS(AceProcessingOptions, AceProcessingOption) + +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + static QString fromAce(const QByteArray &, AceProcessingOptions options = {}); + static QByteArray toAce(const QString &, AceProcessingOptions options = {}); +#else static QString fromAce(const QByteArray &); static QByteArray toAce(const QString &); + static QString fromAce(const QByteArray &, AceProcessingOptions options); + static QByteArray toAce(const QString &, AceProcessingOptions options); +#endif + static QStringList idnWhitelist(); static QStringList toStringList(const QList &uris, FormattingOptions options = FormattingOptions(PrettyDecoded)); static QList fromStringList(const QStringList &uris, ParsingMode mode = TolerantMode); @@ -302,6 +316,7 @@ public: Q_DECLARE_SHARED(QUrl) Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::ComponentFormattingOptions) //Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::FormattingOptions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::AceProcessingOptions) #ifndef Q_QDOC constexpr inline QUrl::FormattingOptions operator|(QUrl::UrlFormattingOption f1, QUrl::UrlFormattingOption f2) diff --git a/src/corelib/io/qurl_p.h b/src/corelib/io/qurl_p.h index 4ba61f6803..9b755cf5df 100644 --- a/src/corelib/io/qurl_p.h +++ b/src/corelib/io/qurl_p.h @@ -65,7 +65,8 @@ extern Q_AUTOTEST_EXPORT qsizetype qt_urlRecode(QString &appendTo, QStringView u // in qurlidna.cpp enum AceLeadingDot { AllowLeadingDot, ForbidLeadingDot }; enum AceOperation { ToAceOnly, NormalizeAce }; -extern QString qt_ACE_do(QStringView domain, AceOperation op, AceLeadingDot dot); +extern QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot, + QUrl::AceProcessingOptions options); extern Q_AUTOTEST_EXPORT void qt_punycodeEncoder(QStringView in, QString *output); extern Q_AUTOTEST_EXPORT QString qt_punycodeDecoder(const QString &pc); diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index 2cc6669b74..31e4ed84d7 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -41,20 +41,12 @@ #include "qurl_p.h" #include -#include #include +#include +#include #include -/* NOTE: IDNA 2003 is based on Unicode 3.2 - - As a result, the assorted Unicode data below snould *not* be updated as part - of our routine updates to UCS (see ../text/qt_attributions.json and - util/unicode/). See QTBUG-85323 and RFCs 3491, 3454. - - TODO (QTBUG-85371): Update to IDNA 2008. -*/ - QT_BEGIN_NAMESPACE // needed by the punycode encoder/decoder @@ -68,2116 +60,6 @@ static const uint initial_n = 128; static constexpr unsigned MaxDomainLabelLength = 63; -struct NameprepCaseFoldingEntry { - char32_t uc; - char16_t mapping[4]; -}; - -inline bool operator<(char32_t one, const NameprepCaseFoldingEntry &other) -{ return one < other.uc; } - -inline bool operator<(const NameprepCaseFoldingEntry &one, char32_t other) -{ return one.uc < other; } - -static const NameprepCaseFoldingEntry NameprepCaseFolding[] = { -/* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x0042, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x0043, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x0044, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x0045, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x0046, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x0047, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x0048, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x0049, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x004A, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x004B, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x004C, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x004D, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x004E, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x004F, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x0050, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x0051, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x0052, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x0053, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x0054, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x0055, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x0056, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x0057, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x0058, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x0059, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x005A, { 0x007A, 0x0000, 0x0000, 0x0000 } },*/ - { 0x00B5, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x00C0, { 0x00E0, 0x0000, 0x0000, 0x0000 } }, - { 0x00C1, { 0x00E1, 0x0000, 0x0000, 0x0000 } }, - { 0x00C2, { 0x00E2, 0x0000, 0x0000, 0x0000 } }, - { 0x00C3, { 0x00E3, 0x0000, 0x0000, 0x0000 } }, - { 0x00C4, { 0x00E4, 0x0000, 0x0000, 0x0000 } }, - { 0x00C5, { 0x00E5, 0x0000, 0x0000, 0x0000 } }, - { 0x00C6, { 0x00E6, 0x0000, 0x0000, 0x0000 } }, - { 0x00C7, { 0x00E7, 0x0000, 0x0000, 0x0000 } }, - { 0x00C8, { 0x00E8, 0x0000, 0x0000, 0x0000 } }, - { 0x00C9, { 0x00E9, 0x0000, 0x0000, 0x0000 } }, - { 0x00CA, { 0x00EA, 0x0000, 0x0000, 0x0000 } }, - { 0x00CB, { 0x00EB, 0x0000, 0x0000, 0x0000 } }, - { 0x00CC, { 0x00EC, 0x0000, 0x0000, 0x0000 } }, - { 0x00CD, { 0x00ED, 0x0000, 0x0000, 0x0000 } }, - { 0x00CE, { 0x00EE, 0x0000, 0x0000, 0x0000 } }, - { 0x00CF, { 0x00EF, 0x0000, 0x0000, 0x0000 } }, - { 0x00D0, { 0x00F0, 0x0000, 0x0000, 0x0000 } }, - { 0x00D1, { 0x00F1, 0x0000, 0x0000, 0x0000 } }, - { 0x00D2, { 0x00F2, 0x0000, 0x0000, 0x0000 } }, - { 0x00D3, { 0x00F3, 0x0000, 0x0000, 0x0000 } }, - { 0x00D4, { 0x00F4, 0x0000, 0x0000, 0x0000 } }, - { 0x00D5, { 0x00F5, 0x0000, 0x0000, 0x0000 } }, - { 0x00D6, { 0x00F6, 0x0000, 0x0000, 0x0000 } }, - { 0x00D8, { 0x00F8, 0x0000, 0x0000, 0x0000 } }, - { 0x00D9, { 0x00F9, 0x0000, 0x0000, 0x0000 } }, - { 0x00DA, { 0x00FA, 0x0000, 0x0000, 0x0000 } }, - { 0x00DB, { 0x00FB, 0x0000, 0x0000, 0x0000 } }, - { 0x00DC, { 0x00FC, 0x0000, 0x0000, 0x0000 } }, - { 0x00DD, { 0x00FD, 0x0000, 0x0000, 0x0000 } }, - { 0x00DE, { 0x00FE, 0x0000, 0x0000, 0x0000 } }, - { 0x00DF, { 0x0073, 0x0073, 0x0000, 0x0000 } }, - { 0x0100, { 0x0101, 0x0000, 0x0000, 0x0000 } }, - { 0x0102, { 0x0103, 0x0000, 0x0000, 0x0000 } }, - { 0x0104, { 0x0105, 0x0000, 0x0000, 0x0000 } }, - { 0x0106, { 0x0107, 0x0000, 0x0000, 0x0000 } }, - { 0x0108, { 0x0109, 0x0000, 0x0000, 0x0000 } }, - { 0x010A, { 0x010B, 0x0000, 0x0000, 0x0000 } }, - { 0x010C, { 0x010D, 0x0000, 0x0000, 0x0000 } }, - { 0x010E, { 0x010F, 0x0000, 0x0000, 0x0000 } }, - { 0x0110, { 0x0111, 0x0000, 0x0000, 0x0000 } }, - { 0x0112, { 0x0113, 0x0000, 0x0000, 0x0000 } }, - { 0x0114, { 0x0115, 0x0000, 0x0000, 0x0000 } }, - { 0x0116, { 0x0117, 0x0000, 0x0000, 0x0000 } }, - { 0x0118, { 0x0119, 0x0000, 0x0000, 0x0000 } }, - { 0x011A, { 0x011B, 0x0000, 0x0000, 0x0000 } }, - { 0x011C, { 0x011D, 0x0000, 0x0000, 0x0000 } }, - { 0x011E, { 0x011F, 0x0000, 0x0000, 0x0000 } }, - { 0x0120, { 0x0121, 0x0000, 0x0000, 0x0000 } }, - { 0x0122, { 0x0123, 0x0000, 0x0000, 0x0000 } }, - { 0x0124, { 0x0125, 0x0000, 0x0000, 0x0000 } }, - { 0x0126, { 0x0127, 0x0000, 0x0000, 0x0000 } }, - { 0x0128, { 0x0129, 0x0000, 0x0000, 0x0000 } }, - { 0x012A, { 0x012B, 0x0000, 0x0000, 0x0000 } }, - { 0x012C, { 0x012D, 0x0000, 0x0000, 0x0000 } }, - { 0x012E, { 0x012F, 0x0000, 0x0000, 0x0000 } }, - { 0x0130, { 0x0069, 0x0307, 0x0000, 0x0000 } }, - { 0x0132, { 0x0133, 0x0000, 0x0000, 0x0000 } }, - { 0x0134, { 0x0135, 0x0000, 0x0000, 0x0000 } }, - { 0x0136, { 0x0137, 0x0000, 0x0000, 0x0000 } }, - { 0x0139, { 0x013A, 0x0000, 0x0000, 0x0000 } }, - { 0x013B, { 0x013C, 0x0000, 0x0000, 0x0000 } }, - { 0x013D, { 0x013E, 0x0000, 0x0000, 0x0000 } }, - { 0x013F, { 0x0140, 0x0000, 0x0000, 0x0000 } }, - { 0x0141, { 0x0142, 0x0000, 0x0000, 0x0000 } }, - { 0x0143, { 0x0144, 0x0000, 0x0000, 0x0000 } }, - { 0x0145, { 0x0146, 0x0000, 0x0000, 0x0000 } }, - { 0x0147, { 0x0148, 0x0000, 0x0000, 0x0000 } }, - { 0x0149, { 0x02BC, 0x006E, 0x0000, 0x0000 } }, - { 0x014A, { 0x014B, 0x0000, 0x0000, 0x0000 } }, - { 0x014C, { 0x014D, 0x0000, 0x0000, 0x0000 } }, - { 0x014E, { 0x014F, 0x0000, 0x0000, 0x0000 } }, - { 0x0150, { 0x0151, 0x0000, 0x0000, 0x0000 } }, - { 0x0152, { 0x0153, 0x0000, 0x0000, 0x0000 } }, - { 0x0154, { 0x0155, 0x0000, 0x0000, 0x0000 } }, - { 0x0156, { 0x0157, 0x0000, 0x0000, 0x0000 } }, - { 0x0158, { 0x0159, 0x0000, 0x0000, 0x0000 } }, - { 0x015A, { 0x015B, 0x0000, 0x0000, 0x0000 } }, - { 0x015C, { 0x015D, 0x0000, 0x0000, 0x0000 } }, - { 0x015E, { 0x015F, 0x0000, 0x0000, 0x0000 } }, - { 0x0160, { 0x0161, 0x0000, 0x0000, 0x0000 } }, - { 0x0162, { 0x0163, 0x0000, 0x0000, 0x0000 } }, - { 0x0164, { 0x0165, 0x0000, 0x0000, 0x0000 } }, - { 0x0166, { 0x0167, 0x0000, 0x0000, 0x0000 } }, - { 0x0168, { 0x0169, 0x0000, 0x0000, 0x0000 } }, - { 0x016A, { 0x016B, 0x0000, 0x0000, 0x0000 } }, - { 0x016C, { 0x016D, 0x0000, 0x0000, 0x0000 } }, - { 0x016E, { 0x016F, 0x0000, 0x0000, 0x0000 } }, - { 0x0170, { 0x0171, 0x0000, 0x0000, 0x0000 } }, - { 0x0172, { 0x0173, 0x0000, 0x0000, 0x0000 } }, - { 0x0174, { 0x0175, 0x0000, 0x0000, 0x0000 } }, - { 0x0176, { 0x0177, 0x0000, 0x0000, 0x0000 } }, - { 0x0178, { 0x00FF, 0x0000, 0x0000, 0x0000 } }, - { 0x0179, { 0x017A, 0x0000, 0x0000, 0x0000 } }, - { 0x017B, { 0x017C, 0x0000, 0x0000, 0x0000 } }, - { 0x017D, { 0x017E, 0x0000, 0x0000, 0x0000 } }, - { 0x017F, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x0181, { 0x0253, 0x0000, 0x0000, 0x0000 } }, - { 0x0182, { 0x0183, 0x0000, 0x0000, 0x0000 } }, - { 0x0184, { 0x0185, 0x0000, 0x0000, 0x0000 } }, - { 0x0186, { 0x0254, 0x0000, 0x0000, 0x0000 } }, - { 0x0187, { 0x0188, 0x0000, 0x0000, 0x0000 } }, - { 0x0189, { 0x0256, 0x0000, 0x0000, 0x0000 } }, - { 0x018A, { 0x0257, 0x0000, 0x0000, 0x0000 } }, - { 0x018B, { 0x018C, 0x0000, 0x0000, 0x0000 } }, - { 0x018E, { 0x01DD, 0x0000, 0x0000, 0x0000 } }, - { 0x018F, { 0x0259, 0x0000, 0x0000, 0x0000 } }, - { 0x0190, { 0x025B, 0x0000, 0x0000, 0x0000 } }, - { 0x0191, { 0x0192, 0x0000, 0x0000, 0x0000 } }, - { 0x0193, { 0x0260, 0x0000, 0x0000, 0x0000 } }, - { 0x0194, { 0x0263, 0x0000, 0x0000, 0x0000 } }, - { 0x0196, { 0x0269, 0x0000, 0x0000, 0x0000 } }, - { 0x0197, { 0x0268, 0x0000, 0x0000, 0x0000 } }, - { 0x0198, { 0x0199, 0x0000, 0x0000, 0x0000 } }, - { 0x019C, { 0x026F, 0x0000, 0x0000, 0x0000 } }, - { 0x019D, { 0x0272, 0x0000, 0x0000, 0x0000 } }, - { 0x019F, { 0x0275, 0x0000, 0x0000, 0x0000 } }, - { 0x01A0, { 0x01A1, 0x0000, 0x0000, 0x0000 } }, - { 0x01A2, { 0x01A3, 0x0000, 0x0000, 0x0000 } }, - { 0x01A4, { 0x01A5, 0x0000, 0x0000, 0x0000 } }, - { 0x01A6, { 0x0280, 0x0000, 0x0000, 0x0000 } }, - { 0x01A7, { 0x01A8, 0x0000, 0x0000, 0x0000 } }, - { 0x01A9, { 0x0283, 0x0000, 0x0000, 0x0000 } }, - { 0x01AC, { 0x01AD, 0x0000, 0x0000, 0x0000 } }, - { 0x01AE, { 0x0288, 0x0000, 0x0000, 0x0000 } }, - { 0x01AF, { 0x01B0, 0x0000, 0x0000, 0x0000 } }, - { 0x01B1, { 0x028A, 0x0000, 0x0000, 0x0000 } }, - { 0x01B2, { 0x028B, 0x0000, 0x0000, 0x0000 } }, - { 0x01B3, { 0x01B4, 0x0000, 0x0000, 0x0000 } }, - { 0x01B5, { 0x01B6, 0x0000, 0x0000, 0x0000 } }, - { 0x01B7, { 0x0292, 0x0000, 0x0000, 0x0000 } }, - { 0x01B8, { 0x01B9, 0x0000, 0x0000, 0x0000 } }, - { 0x01BC, { 0x01BD, 0x0000, 0x0000, 0x0000 } }, - { 0x01C4, { 0x01C6, 0x0000, 0x0000, 0x0000 } }, - { 0x01C5, { 0x01C6, 0x0000, 0x0000, 0x0000 } }, - { 0x01C7, { 0x01C9, 0x0000, 0x0000, 0x0000 } }, - { 0x01C8, { 0x01C9, 0x0000, 0x0000, 0x0000 } }, - { 0x01CA, { 0x01CC, 0x0000, 0x0000, 0x0000 } }, - { 0x01CB, { 0x01CC, 0x0000, 0x0000, 0x0000 } }, - { 0x01CD, { 0x01CE, 0x0000, 0x0000, 0x0000 } }, - { 0x01CF, { 0x01D0, 0x0000, 0x0000, 0x0000 } }, - { 0x01D1, { 0x01D2, 0x0000, 0x0000, 0x0000 } }, - { 0x01D3, { 0x01D4, 0x0000, 0x0000, 0x0000 } }, - { 0x01D5, { 0x01D6, 0x0000, 0x0000, 0x0000 } }, - { 0x01D7, { 0x01D8, 0x0000, 0x0000, 0x0000 } }, - { 0x01D9, { 0x01DA, 0x0000, 0x0000, 0x0000 } }, - { 0x01DB, { 0x01DC, 0x0000, 0x0000, 0x0000 } }, - { 0x01DE, { 0x01DF, 0x0000, 0x0000, 0x0000 } }, - { 0x01E0, { 0x01E1, 0x0000, 0x0000, 0x0000 } }, - { 0x01E2, { 0x01E3, 0x0000, 0x0000, 0x0000 } }, - { 0x01E4, { 0x01E5, 0x0000, 0x0000, 0x0000 } }, - { 0x01E6, { 0x01E7, 0x0000, 0x0000, 0x0000 } }, - { 0x01E8, { 0x01E9, 0x0000, 0x0000, 0x0000 } }, - { 0x01EA, { 0x01EB, 0x0000, 0x0000, 0x0000 } }, - { 0x01EC, { 0x01ED, 0x0000, 0x0000, 0x0000 } }, - { 0x01EE, { 0x01EF, 0x0000, 0x0000, 0x0000 } }, - { 0x01F0, { 0x006A, 0x030C, 0x0000, 0x0000 } }, - { 0x01F1, { 0x01F3, 0x0000, 0x0000, 0x0000 } }, - { 0x01F2, { 0x01F3, 0x0000, 0x0000, 0x0000 } }, - { 0x01F4, { 0x01F5, 0x0000, 0x0000, 0x0000 } }, - { 0x01F6, { 0x0195, 0x0000, 0x0000, 0x0000 } }, - { 0x01F7, { 0x01BF, 0x0000, 0x0000, 0x0000 } }, - { 0x01F8, { 0x01F9, 0x0000, 0x0000, 0x0000 } }, - { 0x01FA, { 0x01FB, 0x0000, 0x0000, 0x0000 } }, - { 0x01FC, { 0x01FD, 0x0000, 0x0000, 0x0000 } }, - { 0x01FE, { 0x01FF, 0x0000, 0x0000, 0x0000 } }, - { 0x0200, { 0x0201, 0x0000, 0x0000, 0x0000 } }, - { 0x0202, { 0x0203, 0x0000, 0x0000, 0x0000 } }, - { 0x0204, { 0x0205, 0x0000, 0x0000, 0x0000 } }, - { 0x0206, { 0x0207, 0x0000, 0x0000, 0x0000 } }, - { 0x0208, { 0x0209, 0x0000, 0x0000, 0x0000 } }, - { 0x020A, { 0x020B, 0x0000, 0x0000, 0x0000 } }, - { 0x020C, { 0x020D, 0x0000, 0x0000, 0x0000 } }, - { 0x020E, { 0x020F, 0x0000, 0x0000, 0x0000 } }, - { 0x0210, { 0x0211, 0x0000, 0x0000, 0x0000 } }, - { 0x0212, { 0x0213, 0x0000, 0x0000, 0x0000 } }, - { 0x0214, { 0x0215, 0x0000, 0x0000, 0x0000 } }, - { 0x0216, { 0x0217, 0x0000, 0x0000, 0x0000 } }, - { 0x0218, { 0x0219, 0x0000, 0x0000, 0x0000 } }, - { 0x021A, { 0x021B, 0x0000, 0x0000, 0x0000 } }, - { 0x021C, { 0x021D, 0x0000, 0x0000, 0x0000 } }, - { 0x021E, { 0x021F, 0x0000, 0x0000, 0x0000 } }, - { 0x0220, { 0x019E, 0x0000, 0x0000, 0x0000 } }, - { 0x0222, { 0x0223, 0x0000, 0x0000, 0x0000 } }, - { 0x0224, { 0x0225, 0x0000, 0x0000, 0x0000 } }, - { 0x0226, { 0x0227, 0x0000, 0x0000, 0x0000 } }, - { 0x0228, { 0x0229, 0x0000, 0x0000, 0x0000 } }, - { 0x022A, { 0x022B, 0x0000, 0x0000, 0x0000 } }, - { 0x022C, { 0x022D, 0x0000, 0x0000, 0x0000 } }, - { 0x022E, { 0x022F, 0x0000, 0x0000, 0x0000 } }, - { 0x0230, { 0x0231, 0x0000, 0x0000, 0x0000 } }, - { 0x0232, { 0x0233, 0x0000, 0x0000, 0x0000 } }, - { 0x0345, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x037A, { 0x0020, 0x03B9, 0x0000, 0x0000 } }, - { 0x0386, { 0x03AC, 0x0000, 0x0000, 0x0000 } }, - { 0x0388, { 0x03AD, 0x0000, 0x0000, 0x0000 } }, - { 0x0389, { 0x03AE, 0x0000, 0x0000, 0x0000 } }, - { 0x038A, { 0x03AF, 0x0000, 0x0000, 0x0000 } }, - { 0x038C, { 0x03CC, 0x0000, 0x0000, 0x0000 } }, - { 0x038E, { 0x03CD, 0x0000, 0x0000, 0x0000 } }, - { 0x038F, { 0x03CE, 0x0000, 0x0000, 0x0000 } }, - { 0x0390, { 0x03B9, 0x0308, 0x0301, 0x0000 } }, - { 0x0391, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x0392, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x0393, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x0394, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x0395, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x0396, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x0397, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x0398, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x0399, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x039A, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x039B, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x039C, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x039D, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x039E, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x039F, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x03A0, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x03A1, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x03A3, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x03A4, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x03A5, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x03A6, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x03A7, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x03A8, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x03A9, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x03AA, { 0x03CA, 0x0000, 0x0000, 0x0000 } }, - { 0x03AB, { 0x03CB, 0x0000, 0x0000, 0x0000 } }, - { 0x03B0, { 0x03C5, 0x0308, 0x0301, 0x0000 } }, - { 0x03C2, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x03D0, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x03D1, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x03D2, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x03D3, { 0x03CD, 0x0000, 0x0000, 0x0000 } }, - { 0x03D4, { 0x03CB, 0x0000, 0x0000, 0x0000 } }, - { 0x03D5, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x03D6, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x03D8, { 0x03D9, 0x0000, 0x0000, 0x0000 } }, - { 0x03DA, { 0x03DB, 0x0000, 0x0000, 0x0000 } }, - { 0x03DC, { 0x03DD, 0x0000, 0x0000, 0x0000 } }, - { 0x03DE, { 0x03DF, 0x0000, 0x0000, 0x0000 } }, - { 0x03E0, { 0x03E1, 0x0000, 0x0000, 0x0000 } }, - { 0x03E2, { 0x03E3, 0x0000, 0x0000, 0x0000 } }, - { 0x03E4, { 0x03E5, 0x0000, 0x0000, 0x0000 } }, - { 0x03E6, { 0x03E7, 0x0000, 0x0000, 0x0000 } }, - { 0x03E8, { 0x03E9, 0x0000, 0x0000, 0x0000 } }, - { 0x03EA, { 0x03EB, 0x0000, 0x0000, 0x0000 } }, - { 0x03EC, { 0x03ED, 0x0000, 0x0000, 0x0000 } }, - { 0x03EE, { 0x03EF, 0x0000, 0x0000, 0x0000 } }, - { 0x03F0, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x03F1, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x03F2, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x03F4, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x03F5, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x0400, { 0x0450, 0x0000, 0x0000, 0x0000 } }, - { 0x0401, { 0x0451, 0x0000, 0x0000, 0x0000 } }, - { 0x0402, { 0x0452, 0x0000, 0x0000, 0x0000 } }, - { 0x0403, { 0x0453, 0x0000, 0x0000, 0x0000 } }, - { 0x0404, { 0x0454, 0x0000, 0x0000, 0x0000 } }, - { 0x0405, { 0x0455, 0x0000, 0x0000, 0x0000 } }, - { 0x0406, { 0x0456, 0x0000, 0x0000, 0x0000 } }, - { 0x0407, { 0x0457, 0x0000, 0x0000, 0x0000 } }, - { 0x0408, { 0x0458, 0x0000, 0x0000, 0x0000 } }, - { 0x0409, { 0x0459, 0x0000, 0x0000, 0x0000 } }, - { 0x040A, { 0x045A, 0x0000, 0x0000, 0x0000 } }, - { 0x040B, { 0x045B, 0x0000, 0x0000, 0x0000 } }, - { 0x040C, { 0x045C, 0x0000, 0x0000, 0x0000 } }, - { 0x040D, { 0x045D, 0x0000, 0x0000, 0x0000 } }, - { 0x040E, { 0x045E, 0x0000, 0x0000, 0x0000 } }, - { 0x040F, { 0x045F, 0x0000, 0x0000, 0x0000 } }, - { 0x0410, { 0x0430, 0x0000, 0x0000, 0x0000 } }, - { 0x0411, { 0x0431, 0x0000, 0x0000, 0x0000 } }, - { 0x0412, { 0x0432, 0x0000, 0x0000, 0x0000 } }, - { 0x0413, { 0x0433, 0x0000, 0x0000, 0x0000 } }, - { 0x0414, { 0x0434, 0x0000, 0x0000, 0x0000 } }, - { 0x0415, { 0x0435, 0x0000, 0x0000, 0x0000 } }, - { 0x0416, { 0x0436, 0x0000, 0x0000, 0x0000 } }, - { 0x0417, { 0x0437, 0x0000, 0x0000, 0x0000 } }, - { 0x0418, { 0x0438, 0x0000, 0x0000, 0x0000 } }, - { 0x0419, { 0x0439, 0x0000, 0x0000, 0x0000 } }, - { 0x041A, { 0x043A, 0x0000, 0x0000, 0x0000 } }, - { 0x041B, { 0x043B, 0x0000, 0x0000, 0x0000 } }, - { 0x041C, { 0x043C, 0x0000, 0x0000, 0x0000 } }, - { 0x041D, { 0x043D, 0x0000, 0x0000, 0x0000 } }, - { 0x041E, { 0x043E, 0x0000, 0x0000, 0x0000 } }, - { 0x041F, { 0x043F, 0x0000, 0x0000, 0x0000 } }, - { 0x0420, { 0x0440, 0x0000, 0x0000, 0x0000 } }, - { 0x0421, { 0x0441, 0x0000, 0x0000, 0x0000 } }, - { 0x0422, { 0x0442, 0x0000, 0x0000, 0x0000 } }, - { 0x0423, { 0x0443, 0x0000, 0x0000, 0x0000 } }, - { 0x0424, { 0x0444, 0x0000, 0x0000, 0x0000 } }, - { 0x0425, { 0x0445, 0x0000, 0x0000, 0x0000 } }, - { 0x0426, { 0x0446, 0x0000, 0x0000, 0x0000 } }, - { 0x0427, { 0x0447, 0x0000, 0x0000, 0x0000 } }, - { 0x0428, { 0x0448, 0x0000, 0x0000, 0x0000 } }, - { 0x0429, { 0x0449, 0x0000, 0x0000, 0x0000 } }, - { 0x042A, { 0x044A, 0x0000, 0x0000, 0x0000 } }, - { 0x042B, { 0x044B, 0x0000, 0x0000, 0x0000 } }, - { 0x042C, { 0x044C, 0x0000, 0x0000, 0x0000 } }, - { 0x042D, { 0x044D, 0x0000, 0x0000, 0x0000 } }, - { 0x042E, { 0x044E, 0x0000, 0x0000, 0x0000 } }, - { 0x042F, { 0x044F, 0x0000, 0x0000, 0x0000 } }, - { 0x0460, { 0x0461, 0x0000, 0x0000, 0x0000 } }, - { 0x0462, { 0x0463, 0x0000, 0x0000, 0x0000 } }, - { 0x0464, { 0x0465, 0x0000, 0x0000, 0x0000 } }, - { 0x0466, { 0x0467, 0x0000, 0x0000, 0x0000 } }, - { 0x0468, { 0x0469, 0x0000, 0x0000, 0x0000 } }, - { 0x046A, { 0x046B, 0x0000, 0x0000, 0x0000 } }, - { 0x046C, { 0x046D, 0x0000, 0x0000, 0x0000 } }, - { 0x046E, { 0x046F, 0x0000, 0x0000, 0x0000 } }, - { 0x0470, { 0x0471, 0x0000, 0x0000, 0x0000 } }, - { 0x0472, { 0x0473, 0x0000, 0x0000, 0x0000 } }, - { 0x0474, { 0x0475, 0x0000, 0x0000, 0x0000 } }, - { 0x0476, { 0x0477, 0x0000, 0x0000, 0x0000 } }, - { 0x0478, { 0x0479, 0x0000, 0x0000, 0x0000 } }, - { 0x047A, { 0x047B, 0x0000, 0x0000, 0x0000 } }, - { 0x047C, { 0x047D, 0x0000, 0x0000, 0x0000 } }, - { 0x047E, { 0x047F, 0x0000, 0x0000, 0x0000 } }, - { 0x0480, { 0x0481, 0x0000, 0x0000, 0x0000 } }, - { 0x048A, { 0x048B, 0x0000, 0x0000, 0x0000 } }, - { 0x048C, { 0x048D, 0x0000, 0x0000, 0x0000 } }, - { 0x048E, { 0x048F, 0x0000, 0x0000, 0x0000 } }, - { 0x0490, { 0x0491, 0x0000, 0x0000, 0x0000 } }, - { 0x0492, { 0x0493, 0x0000, 0x0000, 0x0000 } }, - { 0x0494, { 0x0495, 0x0000, 0x0000, 0x0000 } }, - { 0x0496, { 0x0497, 0x0000, 0x0000, 0x0000 } }, - { 0x0498, { 0x0499, 0x0000, 0x0000, 0x0000 } }, - { 0x049A, { 0x049B, 0x0000, 0x0000, 0x0000 } }, - { 0x049C, { 0x049D, 0x0000, 0x0000, 0x0000 } }, - { 0x049E, { 0x049F, 0x0000, 0x0000, 0x0000 } }, - { 0x04A0, { 0x04A1, 0x0000, 0x0000, 0x0000 } }, - { 0x04A2, { 0x04A3, 0x0000, 0x0000, 0x0000 } }, - { 0x04A4, { 0x04A5, 0x0000, 0x0000, 0x0000 } }, - { 0x04A6, { 0x04A7, 0x0000, 0x0000, 0x0000 } }, - { 0x04A8, { 0x04A9, 0x0000, 0x0000, 0x0000 } }, - { 0x04AA, { 0x04AB, 0x0000, 0x0000, 0x0000 } }, - { 0x04AC, { 0x04AD, 0x0000, 0x0000, 0x0000 } }, - { 0x04AE, { 0x04AF, 0x0000, 0x0000, 0x0000 } }, - { 0x04B0, { 0x04B1, 0x0000, 0x0000, 0x0000 } }, - { 0x04B2, { 0x04B3, 0x0000, 0x0000, 0x0000 } }, - { 0x04B4, { 0x04B5, 0x0000, 0x0000, 0x0000 } }, - { 0x04B6, { 0x04B7, 0x0000, 0x0000, 0x0000 } }, - { 0x04B8, { 0x04B9, 0x0000, 0x0000, 0x0000 } }, - { 0x04BA, { 0x04BB, 0x0000, 0x0000, 0x0000 } }, - { 0x04BC, { 0x04BD, 0x0000, 0x0000, 0x0000 } }, - { 0x04BE, { 0x04BF, 0x0000, 0x0000, 0x0000 } }, - { 0x04C1, { 0x04C2, 0x0000, 0x0000, 0x0000 } }, - { 0x04C3, { 0x04C4, 0x0000, 0x0000, 0x0000 } }, - { 0x04C5, { 0x04C6, 0x0000, 0x0000, 0x0000 } }, - { 0x04C7, { 0x04C8, 0x0000, 0x0000, 0x0000 } }, - { 0x04C9, { 0x04CA, 0x0000, 0x0000, 0x0000 } }, - { 0x04CB, { 0x04CC, 0x0000, 0x0000, 0x0000 } }, - { 0x04CD, { 0x04CE, 0x0000, 0x0000, 0x0000 } }, - { 0x04D0, { 0x04D1, 0x0000, 0x0000, 0x0000 } }, - { 0x04D2, { 0x04D3, 0x0000, 0x0000, 0x0000 } }, - { 0x04D4, { 0x04D5, 0x0000, 0x0000, 0x0000 } }, - { 0x04D6, { 0x04D7, 0x0000, 0x0000, 0x0000 } }, - { 0x04D8, { 0x04D9, 0x0000, 0x0000, 0x0000 } }, - { 0x04DA, { 0x04DB, 0x0000, 0x0000, 0x0000 } }, - { 0x04DC, { 0x04DD, 0x0000, 0x0000, 0x0000 } }, - { 0x04DE, { 0x04DF, 0x0000, 0x0000, 0x0000 } }, - { 0x04E0, { 0x04E1, 0x0000, 0x0000, 0x0000 } }, - { 0x04E2, { 0x04E3, 0x0000, 0x0000, 0x0000 } }, - { 0x04E4, { 0x04E5, 0x0000, 0x0000, 0x0000 } }, - { 0x04E6, { 0x04E7, 0x0000, 0x0000, 0x0000 } }, - { 0x04E8, { 0x04E9, 0x0000, 0x0000, 0x0000 } }, - { 0x04EA, { 0x04EB, 0x0000, 0x0000, 0x0000 } }, - { 0x04EC, { 0x04ED, 0x0000, 0x0000, 0x0000 } }, - { 0x04EE, { 0x04EF, 0x0000, 0x0000, 0x0000 } }, - { 0x04F0, { 0x04F1, 0x0000, 0x0000, 0x0000 } }, - { 0x04F2, { 0x04F3, 0x0000, 0x0000, 0x0000 } }, - { 0x04F4, { 0x04F5, 0x0000, 0x0000, 0x0000 } }, - { 0x04F8, { 0x04F9, 0x0000, 0x0000, 0x0000 } }, - { 0x0500, { 0x0501, 0x0000, 0x0000, 0x0000 } }, - { 0x0502, { 0x0503, 0x0000, 0x0000, 0x0000 } }, - { 0x0504, { 0x0505, 0x0000, 0x0000, 0x0000 } }, - { 0x0506, { 0x0507, 0x0000, 0x0000, 0x0000 } }, - { 0x0508, { 0x0509, 0x0000, 0x0000, 0x0000 } }, - { 0x050A, { 0x050B, 0x0000, 0x0000, 0x0000 } }, - { 0x050C, { 0x050D, 0x0000, 0x0000, 0x0000 } }, - { 0x050E, { 0x050F, 0x0000, 0x0000, 0x0000 } }, - { 0x0531, { 0x0561, 0x0000, 0x0000, 0x0000 } }, - { 0x0532, { 0x0562, 0x0000, 0x0000, 0x0000 } }, - { 0x0533, { 0x0563, 0x0000, 0x0000, 0x0000 } }, - { 0x0534, { 0x0564, 0x0000, 0x0000, 0x0000 } }, - { 0x0535, { 0x0565, 0x0000, 0x0000, 0x0000 } }, - { 0x0536, { 0x0566, 0x0000, 0x0000, 0x0000 } }, - { 0x0537, { 0x0567, 0x0000, 0x0000, 0x0000 } }, - { 0x0538, { 0x0568, 0x0000, 0x0000, 0x0000 } }, - { 0x0539, { 0x0569, 0x0000, 0x0000, 0x0000 } }, - { 0x053A, { 0x056A, 0x0000, 0x0000, 0x0000 } }, - { 0x053B, { 0x056B, 0x0000, 0x0000, 0x0000 } }, - { 0x053C, { 0x056C, 0x0000, 0x0000, 0x0000 } }, - { 0x053D, { 0x056D, 0x0000, 0x0000, 0x0000 } }, - { 0x053E, { 0x056E, 0x0000, 0x0000, 0x0000 } }, - { 0x053F, { 0x056F, 0x0000, 0x0000, 0x0000 } }, - { 0x0540, { 0x0570, 0x0000, 0x0000, 0x0000 } }, - { 0x0541, { 0x0571, 0x0000, 0x0000, 0x0000 } }, - { 0x0542, { 0x0572, 0x0000, 0x0000, 0x0000 } }, - { 0x0543, { 0x0573, 0x0000, 0x0000, 0x0000 } }, - { 0x0544, { 0x0574, 0x0000, 0x0000, 0x0000 } }, - { 0x0545, { 0x0575, 0x0000, 0x0000, 0x0000 } }, - { 0x0546, { 0x0576, 0x0000, 0x0000, 0x0000 } }, - { 0x0547, { 0x0577, 0x0000, 0x0000, 0x0000 } }, - { 0x0548, { 0x0578, 0x0000, 0x0000, 0x0000 } }, - { 0x0549, { 0x0579, 0x0000, 0x0000, 0x0000 } }, - { 0x054A, { 0x057A, 0x0000, 0x0000, 0x0000 } }, - { 0x054B, { 0x057B, 0x0000, 0x0000, 0x0000 } }, - { 0x054C, { 0x057C, 0x0000, 0x0000, 0x0000 } }, - { 0x054D, { 0x057D, 0x0000, 0x0000, 0x0000 } }, - { 0x054E, { 0x057E, 0x0000, 0x0000, 0x0000 } }, - { 0x054F, { 0x057F, 0x0000, 0x0000, 0x0000 } }, - { 0x0550, { 0x0580, 0x0000, 0x0000, 0x0000 } }, - { 0x0551, { 0x0581, 0x0000, 0x0000, 0x0000 } }, - { 0x0552, { 0x0582, 0x0000, 0x0000, 0x0000 } }, - { 0x0553, { 0x0583, 0x0000, 0x0000, 0x0000 } }, - { 0x0554, { 0x0584, 0x0000, 0x0000, 0x0000 } }, - { 0x0555, { 0x0585, 0x0000, 0x0000, 0x0000 } }, - { 0x0556, { 0x0586, 0x0000, 0x0000, 0x0000 } }, - { 0x0587, { 0x0565, 0x0582, 0x0000, 0x0000 } }, - { 0x1E00, { 0x1E01, 0x0000, 0x0000, 0x0000 } }, - { 0x1E02, { 0x1E03, 0x0000, 0x0000, 0x0000 } }, - { 0x1E04, { 0x1E05, 0x0000, 0x0000, 0x0000 } }, - { 0x1E06, { 0x1E07, 0x0000, 0x0000, 0x0000 } }, - { 0x1E08, { 0x1E09, 0x0000, 0x0000, 0x0000 } }, - { 0x1E0A, { 0x1E0B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E0C, { 0x1E0D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E0E, { 0x1E0F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E10, { 0x1E11, 0x0000, 0x0000, 0x0000 } }, - { 0x1E12, { 0x1E13, 0x0000, 0x0000, 0x0000 } }, - { 0x1E14, { 0x1E15, 0x0000, 0x0000, 0x0000 } }, - { 0x1E16, { 0x1E17, 0x0000, 0x0000, 0x0000 } }, - { 0x1E18, { 0x1E19, 0x0000, 0x0000, 0x0000 } }, - { 0x1E1A, { 0x1E1B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E1C, { 0x1E1D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E1E, { 0x1E1F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E20, { 0x1E21, 0x0000, 0x0000, 0x0000 } }, - { 0x1E22, { 0x1E23, 0x0000, 0x0000, 0x0000 } }, - { 0x1E24, { 0x1E25, 0x0000, 0x0000, 0x0000 } }, - { 0x1E26, { 0x1E27, 0x0000, 0x0000, 0x0000 } }, - { 0x1E28, { 0x1E29, 0x0000, 0x0000, 0x0000 } }, - { 0x1E2A, { 0x1E2B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E2C, { 0x1E2D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E2E, { 0x1E2F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E30, { 0x1E31, 0x0000, 0x0000, 0x0000 } }, - { 0x1E32, { 0x1E33, 0x0000, 0x0000, 0x0000 } }, - { 0x1E34, { 0x1E35, 0x0000, 0x0000, 0x0000 } }, - { 0x1E36, { 0x1E37, 0x0000, 0x0000, 0x0000 } }, - { 0x1E38, { 0x1E39, 0x0000, 0x0000, 0x0000 } }, - { 0x1E3A, { 0x1E3B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E3C, { 0x1E3D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E3E, { 0x1E3F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E40, { 0x1E41, 0x0000, 0x0000, 0x0000 } }, - { 0x1E42, { 0x1E43, 0x0000, 0x0000, 0x0000 } }, - { 0x1E44, { 0x1E45, 0x0000, 0x0000, 0x0000 } }, - { 0x1E46, { 0x1E47, 0x0000, 0x0000, 0x0000 } }, - { 0x1E48, { 0x1E49, 0x0000, 0x0000, 0x0000 } }, - { 0x1E4A, { 0x1E4B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E4C, { 0x1E4D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E4E, { 0x1E4F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E50, { 0x1E51, 0x0000, 0x0000, 0x0000 } }, - { 0x1E52, { 0x1E53, 0x0000, 0x0000, 0x0000 } }, - { 0x1E54, { 0x1E55, 0x0000, 0x0000, 0x0000 } }, - { 0x1E56, { 0x1E57, 0x0000, 0x0000, 0x0000 } }, - { 0x1E58, { 0x1E59, 0x0000, 0x0000, 0x0000 } }, - { 0x1E5A, { 0x1E5B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E5C, { 0x1E5D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E5E, { 0x1E5F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E60, { 0x1E61, 0x0000, 0x0000, 0x0000 } }, - { 0x1E62, { 0x1E63, 0x0000, 0x0000, 0x0000 } }, - { 0x1E64, { 0x1E65, 0x0000, 0x0000, 0x0000 } }, - { 0x1E66, { 0x1E67, 0x0000, 0x0000, 0x0000 } }, - { 0x1E68, { 0x1E69, 0x0000, 0x0000, 0x0000 } }, - { 0x1E6A, { 0x1E6B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E6C, { 0x1E6D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E6E, { 0x1E6F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E70, { 0x1E71, 0x0000, 0x0000, 0x0000 } }, - { 0x1E72, { 0x1E73, 0x0000, 0x0000, 0x0000 } }, - { 0x1E74, { 0x1E75, 0x0000, 0x0000, 0x0000 } }, - { 0x1E76, { 0x1E77, 0x0000, 0x0000, 0x0000 } }, - { 0x1E78, { 0x1E79, 0x0000, 0x0000, 0x0000 } }, - { 0x1E7A, { 0x1E7B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E7C, { 0x1E7D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E7E, { 0x1E7F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E80, { 0x1E81, 0x0000, 0x0000, 0x0000 } }, - { 0x1E82, { 0x1E83, 0x0000, 0x0000, 0x0000 } }, - { 0x1E84, { 0x1E85, 0x0000, 0x0000, 0x0000 } }, - { 0x1E86, { 0x1E87, 0x0000, 0x0000, 0x0000 } }, - { 0x1E88, { 0x1E89, 0x0000, 0x0000, 0x0000 } }, - { 0x1E8A, { 0x1E8B, 0x0000, 0x0000, 0x0000 } }, - { 0x1E8C, { 0x1E8D, 0x0000, 0x0000, 0x0000 } }, - { 0x1E8E, { 0x1E8F, 0x0000, 0x0000, 0x0000 } }, - { 0x1E90, { 0x1E91, 0x0000, 0x0000, 0x0000 } }, - { 0x1E92, { 0x1E93, 0x0000, 0x0000, 0x0000 } }, - { 0x1E94, { 0x1E95, 0x0000, 0x0000, 0x0000 } }, - { 0x1E96, { 0x0068, 0x0331, 0x0000, 0x0000 } }, - { 0x1E97, { 0x0074, 0x0308, 0x0000, 0x0000 } }, - { 0x1E98, { 0x0077, 0x030A, 0x0000, 0x0000 } }, - { 0x1E99, { 0x0079, 0x030A, 0x0000, 0x0000 } }, - { 0x1E9A, { 0x0061, 0x02BE, 0x0000, 0x0000 } }, - { 0x1E9B, { 0x1E61, 0x0000, 0x0000, 0x0000 } }, - { 0x1EA0, { 0x1EA1, 0x0000, 0x0000, 0x0000 } }, - { 0x1EA2, { 0x1EA3, 0x0000, 0x0000, 0x0000 } }, - { 0x1EA4, { 0x1EA5, 0x0000, 0x0000, 0x0000 } }, - { 0x1EA6, { 0x1EA7, 0x0000, 0x0000, 0x0000 } }, - { 0x1EA8, { 0x1EA9, 0x0000, 0x0000, 0x0000 } }, - { 0x1EAA, { 0x1EAB, 0x0000, 0x0000, 0x0000 } }, - { 0x1EAC, { 0x1EAD, 0x0000, 0x0000, 0x0000 } }, - { 0x1EAE, { 0x1EAF, 0x0000, 0x0000, 0x0000 } }, - { 0x1EB0, { 0x1EB1, 0x0000, 0x0000, 0x0000 } }, - { 0x1EB2, { 0x1EB3, 0x0000, 0x0000, 0x0000 } }, - { 0x1EB4, { 0x1EB5, 0x0000, 0x0000, 0x0000 } }, - { 0x1EB6, { 0x1EB7, 0x0000, 0x0000, 0x0000 } }, - { 0x1EB8, { 0x1EB9, 0x0000, 0x0000, 0x0000 } }, - { 0x1EBA, { 0x1EBB, 0x0000, 0x0000, 0x0000 } }, - { 0x1EBC, { 0x1EBD, 0x0000, 0x0000, 0x0000 } }, - { 0x1EBE, { 0x1EBF, 0x0000, 0x0000, 0x0000 } }, - { 0x1EC0, { 0x1EC1, 0x0000, 0x0000, 0x0000 } }, - { 0x1EC2, { 0x1EC3, 0x0000, 0x0000, 0x0000 } }, - { 0x1EC4, { 0x1EC5, 0x0000, 0x0000, 0x0000 } }, - { 0x1EC6, { 0x1EC7, 0x0000, 0x0000, 0x0000 } }, - { 0x1EC8, { 0x1EC9, 0x0000, 0x0000, 0x0000 } }, - { 0x1ECA, { 0x1ECB, 0x0000, 0x0000, 0x0000 } }, - { 0x1ECC, { 0x1ECD, 0x0000, 0x0000, 0x0000 } }, - { 0x1ECE, { 0x1ECF, 0x0000, 0x0000, 0x0000 } }, - { 0x1ED0, { 0x1ED1, 0x0000, 0x0000, 0x0000 } }, - { 0x1ED2, { 0x1ED3, 0x0000, 0x0000, 0x0000 } }, - { 0x1ED4, { 0x1ED5, 0x0000, 0x0000, 0x0000 } }, - { 0x1ED6, { 0x1ED7, 0x0000, 0x0000, 0x0000 } }, - { 0x1ED8, { 0x1ED9, 0x0000, 0x0000, 0x0000 } }, - { 0x1EDA, { 0x1EDB, 0x0000, 0x0000, 0x0000 } }, - { 0x1EDC, { 0x1EDD, 0x0000, 0x0000, 0x0000 } }, - { 0x1EDE, { 0x1EDF, 0x0000, 0x0000, 0x0000 } }, - { 0x1EE0, { 0x1EE1, 0x0000, 0x0000, 0x0000 } }, - { 0x1EE2, { 0x1EE3, 0x0000, 0x0000, 0x0000 } }, - { 0x1EE4, { 0x1EE5, 0x0000, 0x0000, 0x0000 } }, - { 0x1EE6, { 0x1EE7, 0x0000, 0x0000, 0x0000 } }, - { 0x1EE8, { 0x1EE9, 0x0000, 0x0000, 0x0000 } }, - { 0x1EEA, { 0x1EEB, 0x0000, 0x0000, 0x0000 } }, - { 0x1EEC, { 0x1EED, 0x0000, 0x0000, 0x0000 } }, - { 0x1EEE, { 0x1EEF, 0x0000, 0x0000, 0x0000 } }, - { 0x1EF0, { 0x1EF1, 0x0000, 0x0000, 0x0000 } }, - { 0x1EF2, { 0x1EF3, 0x0000, 0x0000, 0x0000 } }, - { 0x1EF4, { 0x1EF5, 0x0000, 0x0000, 0x0000 } }, - { 0x1EF6, { 0x1EF7, 0x0000, 0x0000, 0x0000 } }, - { 0x1EF8, { 0x1EF9, 0x0000, 0x0000, 0x0000 } }, - { 0x1F08, { 0x1F00, 0x0000, 0x0000, 0x0000 } }, - { 0x1F09, { 0x1F01, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0A, { 0x1F02, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0B, { 0x1F03, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0C, { 0x1F04, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0D, { 0x1F05, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0E, { 0x1F06, 0x0000, 0x0000, 0x0000 } }, - { 0x1F0F, { 0x1F07, 0x0000, 0x0000, 0x0000 } }, - { 0x1F18, { 0x1F10, 0x0000, 0x0000, 0x0000 } }, - { 0x1F19, { 0x1F11, 0x0000, 0x0000, 0x0000 } }, - { 0x1F1A, { 0x1F12, 0x0000, 0x0000, 0x0000 } }, - { 0x1F1B, { 0x1F13, 0x0000, 0x0000, 0x0000 } }, - { 0x1F1C, { 0x1F14, 0x0000, 0x0000, 0x0000 } }, - { 0x1F1D, { 0x1F15, 0x0000, 0x0000, 0x0000 } }, - { 0x1F28, { 0x1F20, 0x0000, 0x0000, 0x0000 } }, - { 0x1F29, { 0x1F21, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2A, { 0x1F22, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2B, { 0x1F23, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2C, { 0x1F24, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2D, { 0x1F25, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2E, { 0x1F26, 0x0000, 0x0000, 0x0000 } }, - { 0x1F2F, { 0x1F27, 0x0000, 0x0000, 0x0000 } }, - { 0x1F38, { 0x1F30, 0x0000, 0x0000, 0x0000 } }, - { 0x1F39, { 0x1F31, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3A, { 0x1F32, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3B, { 0x1F33, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3C, { 0x1F34, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3D, { 0x1F35, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3E, { 0x1F36, 0x0000, 0x0000, 0x0000 } }, - { 0x1F3F, { 0x1F37, 0x0000, 0x0000, 0x0000 } }, - { 0x1F48, { 0x1F40, 0x0000, 0x0000, 0x0000 } }, - { 0x1F49, { 0x1F41, 0x0000, 0x0000, 0x0000 } }, - { 0x1F4A, { 0x1F42, 0x0000, 0x0000, 0x0000 } }, - { 0x1F4B, { 0x1F43, 0x0000, 0x0000, 0x0000 } }, - { 0x1F4C, { 0x1F44, 0x0000, 0x0000, 0x0000 } }, - { 0x1F4D, { 0x1F45, 0x0000, 0x0000, 0x0000 } }, - { 0x1F50, { 0x03C5, 0x0313, 0x0000, 0x0000 } }, - { 0x1F52, { 0x03C5, 0x0313, 0x0300, 0x0000 } }, - { 0x1F54, { 0x03C5, 0x0313, 0x0301, 0x0000 } }, - { 0x1F56, { 0x03C5, 0x0313, 0x0342, 0x0000 } }, - { 0x1F59, { 0x1F51, 0x0000, 0x0000, 0x0000 } }, - { 0x1F5B, { 0x1F53, 0x0000, 0x0000, 0x0000 } }, - { 0x1F5D, { 0x1F55, 0x0000, 0x0000, 0x0000 } }, - { 0x1F5F, { 0x1F57, 0x0000, 0x0000, 0x0000 } }, - { 0x1F68, { 0x1F60, 0x0000, 0x0000, 0x0000 } }, - { 0x1F69, { 0x1F61, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6A, { 0x1F62, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6B, { 0x1F63, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6C, { 0x1F64, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6D, { 0x1F65, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6E, { 0x1F66, 0x0000, 0x0000, 0x0000 } }, - { 0x1F6F, { 0x1F67, 0x0000, 0x0000, 0x0000 } }, - { 0x1F80, { 0x1F00, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F81, { 0x1F01, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F82, { 0x1F02, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F83, { 0x1F03, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F84, { 0x1F04, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F85, { 0x1F05, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F86, { 0x1F06, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F87, { 0x1F07, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F88, { 0x1F00, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F89, { 0x1F01, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8A, { 0x1F02, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8B, { 0x1F03, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8C, { 0x1F04, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8D, { 0x1F05, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8E, { 0x1F06, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F8F, { 0x1F07, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F90, { 0x1F20, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F91, { 0x1F21, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F92, { 0x1F22, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F93, { 0x1F23, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F94, { 0x1F24, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F95, { 0x1F25, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F96, { 0x1F26, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F97, { 0x1F27, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F98, { 0x1F20, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F99, { 0x1F21, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9A, { 0x1F22, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9B, { 0x1F23, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9C, { 0x1F24, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9D, { 0x1F25, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9E, { 0x1F26, 0x03B9, 0x0000, 0x0000 } }, - { 0x1F9F, { 0x1F27, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA0, { 0x1F60, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA1, { 0x1F61, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA2, { 0x1F62, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA3, { 0x1F63, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA4, { 0x1F64, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA5, { 0x1F65, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA6, { 0x1F66, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA7, { 0x1F67, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA8, { 0x1F60, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FA9, { 0x1F61, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAA, { 0x1F62, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAB, { 0x1F63, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAC, { 0x1F64, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAD, { 0x1F65, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAE, { 0x1F66, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FAF, { 0x1F67, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FB2, { 0x1F70, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FB3, { 0x03B1, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FB4, { 0x03AC, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FB6, { 0x03B1, 0x0342, 0x0000, 0x0000 } }, - { 0x1FB7, { 0x03B1, 0x0342, 0x03B9, 0x0000 } }, - { 0x1FB8, { 0x1FB0, 0x0000, 0x0000, 0x0000 } }, - { 0x1FB9, { 0x1FB1, 0x0000, 0x0000, 0x0000 } }, - { 0x1FBA, { 0x1F70, 0x0000, 0x0000, 0x0000 } }, - { 0x1FBB, { 0x1F71, 0x0000, 0x0000, 0x0000 } }, - { 0x1FBC, { 0x03B1, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FBE, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1FC2, { 0x1F74, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FC3, { 0x03B7, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FC4, { 0x03AE, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FC6, { 0x03B7, 0x0342, 0x0000, 0x0000 } }, - { 0x1FC7, { 0x03B7, 0x0342, 0x03B9, 0x0000 } }, - { 0x1FC8, { 0x1F72, 0x0000, 0x0000, 0x0000 } }, - { 0x1FC9, { 0x1F73, 0x0000, 0x0000, 0x0000 } }, - { 0x1FCA, { 0x1F74, 0x0000, 0x0000, 0x0000 } }, - { 0x1FCB, { 0x1F75, 0x0000, 0x0000, 0x0000 } }, - { 0x1FCC, { 0x03B7, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FD2, { 0x03B9, 0x0308, 0x0300, 0x0000 } }, - { 0x1FD3, { 0x03B9, 0x0308, 0x0301, 0x0000 } }, - { 0x1FD6, { 0x03B9, 0x0342, 0x0000, 0x0000 } }, - { 0x1FD7, { 0x03B9, 0x0308, 0x0342, 0x0000 } }, - { 0x1FD8, { 0x1FD0, 0x0000, 0x0000, 0x0000 } }, - { 0x1FD9, { 0x1FD1, 0x0000, 0x0000, 0x0000 } }, - { 0x1FDA, { 0x1F76, 0x0000, 0x0000, 0x0000 } }, - { 0x1FDB, { 0x1F77, 0x0000, 0x0000, 0x0000 } }, - { 0x1FE2, { 0x03C5, 0x0308, 0x0300, 0x0000 } }, - { 0x1FE3, { 0x03C5, 0x0308, 0x0301, 0x0000 } }, - { 0x1FE4, { 0x03C1, 0x0313, 0x0000, 0x0000 } }, - { 0x1FE6, { 0x03C5, 0x0342, 0x0000, 0x0000 } }, - { 0x1FE7, { 0x03C5, 0x0308, 0x0342, 0x0000 } }, - { 0x1FE8, { 0x1FE0, 0x0000, 0x0000, 0x0000 } }, - { 0x1FE9, { 0x1FE1, 0x0000, 0x0000, 0x0000 } }, - { 0x1FEA, { 0x1F7A, 0x0000, 0x0000, 0x0000 } }, - { 0x1FEB, { 0x1F7B, 0x0000, 0x0000, 0x0000 } }, - { 0x1FEC, { 0x1FE5, 0x0000, 0x0000, 0x0000 } }, - { 0x1FF2, { 0x1F7C, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FF3, { 0x03C9, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FF4, { 0x03CE, 0x03B9, 0x0000, 0x0000 } }, - { 0x1FF6, { 0x03C9, 0x0342, 0x0000, 0x0000 } }, - { 0x1FF7, { 0x03C9, 0x0342, 0x03B9, 0x0000 } }, - { 0x1FF8, { 0x1F78, 0x0000, 0x0000, 0x0000 } }, - { 0x1FF9, { 0x1F79, 0x0000, 0x0000, 0x0000 } }, - { 0x1FFA, { 0x1F7C, 0x0000, 0x0000, 0x0000 } }, - { 0x1FFB, { 0x1F7D, 0x0000, 0x0000, 0x0000 } }, - { 0x1FFC, { 0x03C9, 0x03B9, 0x0000, 0x0000 } }, - { 0x20A8, { 0x0072, 0x0073, 0x0000, 0x0000 } }, - { 0x2102, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x2103, { 0x00B0, 0x0063, 0x0000, 0x0000 } }, - { 0x2107, { 0x025B, 0x0000, 0x0000, 0x0000 } }, - { 0x2109, { 0x00B0, 0x0066, 0x0000, 0x0000 } }, - { 0x210B, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x210C, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x210D, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x2110, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x2111, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x2112, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x2115, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x2116, { 0x006E, 0x006F, 0x0000, 0x0000 } }, - { 0x2119, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x211A, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x211B, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x211C, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x211D, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x2120, { 0x0073, 0x006D, 0x0000, 0x0000 } }, - { 0x2121, { 0x0074, 0x0065, 0x006C, 0x0000 } }, - { 0x2122, { 0x0074, 0x006D, 0x0000, 0x0000 } }, - { 0x2124, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x2126, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x2128, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x212A, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x212B, { 0x00E5, 0x0000, 0x0000, 0x0000 } }, - { 0x212C, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x212D, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x2130, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x2131, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x2133, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x213E, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x213F, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x2145, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x2160, { 0x2170, 0x0000, 0x0000, 0x0000 } }, - { 0x2161, { 0x2171, 0x0000, 0x0000, 0x0000 } }, - { 0x2162, { 0x2172, 0x0000, 0x0000, 0x0000 } }, - { 0x2163, { 0x2173, 0x0000, 0x0000, 0x0000 } }, - { 0x2164, { 0x2174, 0x0000, 0x0000, 0x0000 } }, - { 0x2165, { 0x2175, 0x0000, 0x0000, 0x0000 } }, - { 0x2166, { 0x2176, 0x0000, 0x0000, 0x0000 } }, - { 0x2167, { 0x2177, 0x0000, 0x0000, 0x0000 } }, - { 0x2168, { 0x2178, 0x0000, 0x0000, 0x0000 } }, - { 0x2169, { 0x2179, 0x0000, 0x0000, 0x0000 } }, - { 0x216A, { 0x217A, 0x0000, 0x0000, 0x0000 } }, - { 0x216B, { 0x217B, 0x0000, 0x0000, 0x0000 } }, - { 0x216C, { 0x217C, 0x0000, 0x0000, 0x0000 } }, - { 0x216D, { 0x217D, 0x0000, 0x0000, 0x0000 } }, - { 0x216E, { 0x217E, 0x0000, 0x0000, 0x0000 } }, - { 0x216F, { 0x217F, 0x0000, 0x0000, 0x0000 } }, - { 0x24B6, { 0x24D0, 0x0000, 0x0000, 0x0000 } }, - { 0x24B7, { 0x24D1, 0x0000, 0x0000, 0x0000 } }, - { 0x24B8, { 0x24D2, 0x0000, 0x0000, 0x0000 } }, - { 0x24B9, { 0x24D3, 0x0000, 0x0000, 0x0000 } }, - { 0x24BA, { 0x24D4, 0x0000, 0x0000, 0x0000 } }, - { 0x24BB, { 0x24D5, 0x0000, 0x0000, 0x0000 } }, - { 0x24BC, { 0x24D6, 0x0000, 0x0000, 0x0000 } }, - { 0x24BD, { 0x24D7, 0x0000, 0x0000, 0x0000 } }, - { 0x24BE, { 0x24D8, 0x0000, 0x0000, 0x0000 } }, - { 0x24BF, { 0x24D9, 0x0000, 0x0000, 0x0000 } }, - { 0x24C0, { 0x24DA, 0x0000, 0x0000, 0x0000 } }, - { 0x24C1, { 0x24DB, 0x0000, 0x0000, 0x0000 } }, - { 0x24C2, { 0x24DC, 0x0000, 0x0000, 0x0000 } }, - { 0x24C3, { 0x24DD, 0x0000, 0x0000, 0x0000 } }, - { 0x24C4, { 0x24DE, 0x0000, 0x0000, 0x0000 } }, - { 0x24C5, { 0x24DF, 0x0000, 0x0000, 0x0000 } }, - { 0x24C6, { 0x24E0, 0x0000, 0x0000, 0x0000 } }, - { 0x24C7, { 0x24E1, 0x0000, 0x0000, 0x0000 } }, - { 0x24C8, { 0x24E2, 0x0000, 0x0000, 0x0000 } }, - { 0x24C9, { 0x24E3, 0x0000, 0x0000, 0x0000 } }, - { 0x24CA, { 0x24E4, 0x0000, 0x0000, 0x0000 } }, - { 0x24CB, { 0x24E5, 0x0000, 0x0000, 0x0000 } }, - { 0x24CC, { 0x24E6, 0x0000, 0x0000, 0x0000 } }, - { 0x24CD, { 0x24E7, 0x0000, 0x0000, 0x0000 } }, - { 0x24CE, { 0x24E8, 0x0000, 0x0000, 0x0000 } }, - { 0x24CF, { 0x24E9, 0x0000, 0x0000, 0x0000 } }, - { 0x3371, { 0x0068, 0x0070, 0x0061, 0x0000 } }, - { 0x3373, { 0x0061, 0x0075, 0x0000, 0x0000 } }, - { 0x3375, { 0x006F, 0x0076, 0x0000, 0x0000 } }, - { 0x3380, { 0x0070, 0x0061, 0x0000, 0x0000 } }, - { 0x3381, { 0x006E, 0x0061, 0x0000, 0x0000 } }, - { 0x3382, { 0x03BC, 0x0061, 0x0000, 0x0000 } }, - { 0x3383, { 0x006D, 0x0061, 0x0000, 0x0000 } }, - { 0x3384, { 0x006B, 0x0061, 0x0000, 0x0000 } }, - { 0x3385, { 0x006B, 0x0062, 0x0000, 0x0000 } }, - { 0x3386, { 0x006D, 0x0062, 0x0000, 0x0000 } }, - { 0x3387, { 0x0067, 0x0062, 0x0000, 0x0000 } }, - { 0x338A, { 0x0070, 0x0066, 0x0000, 0x0000 } }, - { 0x338B, { 0x006E, 0x0066, 0x0000, 0x0000 } }, - { 0x338C, { 0x03BC, 0x0066, 0x0000, 0x0000 } }, - { 0x3390, { 0x0068, 0x007A, 0x0000, 0x0000 } }, - { 0x3391, { 0x006B, 0x0068, 0x007A, 0x0000 } }, - { 0x3392, { 0x006D, 0x0068, 0x007A, 0x0000 } }, - { 0x3393, { 0x0067, 0x0068, 0x007A, 0x0000 } }, - { 0x3394, { 0x0074, 0x0068, 0x007A, 0x0000 } }, - { 0x33A9, { 0x0070, 0x0061, 0x0000, 0x0000 } }, - { 0x33AA, { 0x006B, 0x0070, 0x0061, 0x0000 } }, - { 0x33AB, { 0x006D, 0x0070, 0x0061, 0x0000 } }, - { 0x33AC, { 0x0067, 0x0070, 0x0061, 0x0000 } }, - { 0x33B4, { 0x0070, 0x0076, 0x0000, 0x0000 } }, - { 0x33B5, { 0x006E, 0x0076, 0x0000, 0x0000 } }, - { 0x33B6, { 0x03BC, 0x0076, 0x0000, 0x0000 } }, - { 0x33B7, { 0x006D, 0x0076, 0x0000, 0x0000 } }, - { 0x33B8, { 0x006B, 0x0076, 0x0000, 0x0000 } }, - { 0x33B9, { 0x006D, 0x0076, 0x0000, 0x0000 } }, - { 0x33BA, { 0x0070, 0x0077, 0x0000, 0x0000 } }, - { 0x33BB, { 0x006E, 0x0077, 0x0000, 0x0000 } }, - { 0x33BC, { 0x03BC, 0x0077, 0x0000, 0x0000 } }, - { 0x33BD, { 0x006D, 0x0077, 0x0000, 0x0000 } }, - { 0x33BE, { 0x006B, 0x0077, 0x0000, 0x0000 } }, - { 0x33BF, { 0x006D, 0x0077, 0x0000, 0x0000 } }, - { 0x33C0, { 0x006B, 0x03C9, 0x0000, 0x0000 } }, - { 0x33C1, { 0x006D, 0x03C9, 0x0000, 0x0000 } }, - { 0x33C3, { 0x0062, 0x0071, 0x0000, 0x0000 } }, - { 0x33C6, { 0x0063, 0x2215, 0x006B, 0x0067 } }, - { 0x33C7, { 0x0063, 0x006F, 0x002E, 0x0000 } }, - { 0x33C8, { 0x0064, 0x0062, 0x0000, 0x0000 } }, - { 0x33C9, { 0x0067, 0x0079, 0x0000, 0x0000 } }, - { 0x33CB, { 0x0068, 0x0070, 0x0000, 0x0000 } }, - { 0x33CD, { 0x006B, 0x006B, 0x0000, 0x0000 } }, - { 0x33CE, { 0x006B, 0x006D, 0x0000, 0x0000 } }, - { 0x33D7, { 0x0070, 0x0068, 0x0000, 0x0000 } }, - { 0x33D9, { 0x0070, 0x0070, 0x006D, 0x0000 } }, - { 0x33DA, { 0x0070, 0x0072, 0x0000, 0x0000 } }, - { 0x33DC, { 0x0073, 0x0076, 0x0000, 0x0000 } }, - { 0x33DD, { 0x0077, 0x0062, 0x0000, 0x0000 } }, - { 0xFB00, { 0x0066, 0x0066, 0x0000, 0x0000 } }, - { 0xFB01, { 0x0066, 0x0069, 0x0000, 0x0000 } }, - { 0xFB02, { 0x0066, 0x006C, 0x0000, 0x0000 } }, - { 0xFB03, { 0x0066, 0x0066, 0x0069, 0x0000 } }, - { 0xFB04, { 0x0066, 0x0066, 0x006C, 0x0000 } }, - { 0xFB05, { 0x0073, 0x0074, 0x0000, 0x0000 } }, - { 0xFB06, { 0x0073, 0x0074, 0x0000, 0x0000 } }, - { 0xFB13, { 0x0574, 0x0576, 0x0000, 0x0000 } }, - { 0xFB14, { 0x0574, 0x0565, 0x0000, 0x0000 } }, - { 0xFB15, { 0x0574, 0x056B, 0x0000, 0x0000 } }, - { 0xFB16, { 0x057E, 0x0576, 0x0000, 0x0000 } }, - { 0xFB17, { 0x0574, 0x056D, 0x0000, 0x0000 } }, - { 0xFF21, { 0xFF41, 0x0000, 0x0000, 0x0000 } }, - { 0xFF22, { 0xFF42, 0x0000, 0x0000, 0x0000 } }, - { 0xFF23, { 0xFF43, 0x0000, 0x0000, 0x0000 } }, - { 0xFF24, { 0xFF44, 0x0000, 0x0000, 0x0000 } }, - { 0xFF25, { 0xFF45, 0x0000, 0x0000, 0x0000 } }, - { 0xFF26, { 0xFF46, 0x0000, 0x0000, 0x0000 } }, - { 0xFF27, { 0xFF47, 0x0000, 0x0000, 0x0000 } }, - { 0xFF28, { 0xFF48, 0x0000, 0x0000, 0x0000 } }, - { 0xFF29, { 0xFF49, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2A, { 0xFF4A, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2B, { 0xFF4B, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2C, { 0xFF4C, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2D, { 0xFF4D, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2E, { 0xFF4E, 0x0000, 0x0000, 0x0000 } }, - { 0xFF2F, { 0xFF4F, 0x0000, 0x0000, 0x0000 } }, - { 0xFF30, { 0xFF50, 0x0000, 0x0000, 0x0000 } }, - { 0xFF31, { 0xFF51, 0x0000, 0x0000, 0x0000 } }, - { 0xFF32, { 0xFF52, 0x0000, 0x0000, 0x0000 } }, - { 0xFF33, { 0xFF53, 0x0000, 0x0000, 0x0000 } }, - { 0xFF34, { 0xFF54, 0x0000, 0x0000, 0x0000 } }, - { 0xFF35, { 0xFF55, 0x0000, 0x0000, 0x0000 } }, - { 0xFF36, { 0xFF56, 0x0000, 0x0000, 0x0000 } }, - { 0xFF37, { 0xFF57, 0x0000, 0x0000, 0x0000 } }, - { 0xFF38, { 0xFF58, 0x0000, 0x0000, 0x0000 } }, - { 0xFF39, { 0xFF59, 0x0000, 0x0000, 0x0000 } }, - { 0xFF3A, { 0xFF5A, 0x0000, 0x0000, 0x0000 } }, - { 0x10400, { 0xd801, 0xdc28, 0x0000, 0x0000 } }, - { 0x10401, { 0xd801, 0xdc29, 0x0000, 0x0000 } }, - { 0x10402, { 0xd801, 0xdc2A, 0x0000, 0x0000 } }, - { 0x10403, { 0xd801, 0xdc2B, 0x0000, 0x0000 } }, - { 0x10404, { 0xd801, 0xdc2C, 0x0000, 0x0000 } }, - { 0x10405, { 0xd801, 0xdc2D, 0x0000, 0x0000 } }, - { 0x10406, { 0xd801, 0xdc2E, 0x0000, 0x0000 } }, - { 0x10407, { 0xd801, 0xdc2F, 0x0000, 0x0000 } }, - { 0x10408, { 0xd801, 0xdc30, 0x0000, 0x0000 } }, - { 0x10409, { 0xd801, 0xdc31, 0x0000, 0x0000 } }, - { 0x1040A, { 0xd801, 0xdc32, 0x0000, 0x0000 } }, - { 0x1040B, { 0xd801, 0xdc33, 0x0000, 0x0000 } }, - { 0x1040C, { 0xd801, 0xdc34, 0x0000, 0x0000 } }, - { 0x1040D, { 0xd801, 0xdc35, 0x0000, 0x0000 } }, - { 0x1040E, { 0xd801, 0xdc36, 0x0000, 0x0000 } }, - { 0x1040F, { 0xd801, 0xdc37, 0x0000, 0x0000 } }, - { 0x10410, { 0xd801, 0xdc38, 0x0000, 0x0000 } }, - { 0x10411, { 0xd801, 0xdc39, 0x0000, 0x0000 } }, - { 0x10412, { 0xd801, 0xdc3A, 0x0000, 0x0000 } }, - { 0x10413, { 0xd801, 0xdc3B, 0x0000, 0x0000 } }, - { 0x10414, { 0xd801, 0xdc3C, 0x0000, 0x0000 } }, - { 0x10415, { 0xd801, 0xdc3D, 0x0000, 0x0000 } }, - { 0x10416, { 0xd801, 0xdc3E, 0x0000, 0x0000 } }, - { 0x10417, { 0xd801, 0xdc3F, 0x0000, 0x0000 } }, - { 0x10418, { 0xd801, 0xdc40, 0x0000, 0x0000 } }, - { 0x10419, { 0xd801, 0xdc41, 0x0000, 0x0000 } }, - { 0x1041A, { 0xd801, 0xdc42, 0x0000, 0x0000 } }, - { 0x1041B, { 0xd801, 0xdc43, 0x0000, 0x0000 } }, - { 0x1041C, { 0xd801, 0xdc44, 0x0000, 0x0000 } }, - { 0x1041D, { 0xd801, 0xdc45, 0x0000, 0x0000 } }, - { 0x1041E, { 0xd801, 0xdc46, 0x0000, 0x0000 } }, - { 0x1041F, { 0xd801, 0xdc47, 0x0000, 0x0000 } }, - { 0x10420, { 0xd801, 0xdc48, 0x0000, 0x0000 } }, - { 0x10421, { 0xd801, 0xdc49, 0x0000, 0x0000 } }, - { 0x10422, { 0xd801, 0xdc4A, 0x0000, 0x0000 } }, - { 0x10423, { 0xd801, 0xdc4B, 0x0000, 0x0000 } }, - { 0x10424, { 0xd801, 0xdc4C, 0x0000, 0x0000 } }, - { 0x10425, { 0xd801, 0xdc4D, 0x0000, 0x0000 } }, - { 0x1D400, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D401, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D402, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D403, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D404, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D405, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D406, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D407, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D408, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D409, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40A, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40B, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40C, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40D, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40E, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D40F, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D410, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D411, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D412, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D413, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D414, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D415, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D416, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D417, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D418, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D419, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D434, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D435, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D436, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D437, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D438, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D439, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43A, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43B, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43C, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43D, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43E, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D43F, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D440, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D441, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D442, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D443, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D444, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D445, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D446, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D447, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D448, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D449, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D44A, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D44B, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D44C, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D44D, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D468, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D469, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46A, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46B, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46C, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46D, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46E, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D46F, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D470, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D471, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D472, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D473, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D474, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D475, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D476, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D477, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D478, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D479, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47A, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47B, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47C, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47D, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47E, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D47F, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D480, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D481, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D49C, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D49E, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D49F, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4A2, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4A5, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4A6, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4A9, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4AA, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4AB, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4AC, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4AE, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4AF, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B0, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B1, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B2, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B3, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B4, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4B5, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D0, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D1, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D2, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D3, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D4, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D5, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D6, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D7, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D8, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4D9, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DA, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DB, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DC, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DD, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DE, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4DF, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E0, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E1, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E2, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E3, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E4, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E5, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E6, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E7, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E8, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D4E9, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D504, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D505, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D507, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D508, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D509, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D50A, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D50D, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D50E, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D50F, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D510, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D511, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D512, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D513, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D514, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D516, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D517, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D518, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D519, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D51A, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D51B, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D51C, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D538, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D539, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D53B, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D53C, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D53D, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D53E, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D540, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D541, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D542, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D543, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D544, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D546, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54A, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54B, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54C, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54D, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54E, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D54F, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D550, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D56C, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D56D, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D56E, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D56F, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D570, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D571, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D572, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D573, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D574, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D575, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D576, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D577, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D578, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D579, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57A, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57B, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57C, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57D, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57E, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D57F, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D580, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D581, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D582, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D583, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D584, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D585, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A0, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A1, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A2, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A3, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A4, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A5, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A6, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A7, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A8, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5A9, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AA, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AB, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AC, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AD, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AE, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5AF, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B0, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B1, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B2, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B3, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B4, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B5, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B6, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B7, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B8, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5B9, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D4, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D5, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D6, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D7, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D8, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5D9, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DA, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DB, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DC, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DD, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DE, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5DF, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E0, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E1, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E2, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E3, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E4, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E5, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E6, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E7, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E8, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5E9, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5EA, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5EB, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5EC, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D5ED, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D608, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D609, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60A, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60B, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60C, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60D, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60E, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D60F, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D610, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D611, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D612, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D613, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D614, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D615, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D616, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D617, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D618, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D619, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61A, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61B, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61C, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61D, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61E, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D61F, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D620, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D621, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D63C, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D63D, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D63E, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D63F, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D640, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D641, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D642, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D643, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D644, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D645, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D646, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D647, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D648, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D649, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64A, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64B, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64C, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64D, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64E, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D64F, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D650, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D651, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D652, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D653, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D654, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D655, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D670, { 0x0061, 0x0000, 0x0000, 0x0000 } }, - { 0x1D671, { 0x0062, 0x0000, 0x0000, 0x0000 } }, - { 0x1D672, { 0x0063, 0x0000, 0x0000, 0x0000 } }, - { 0x1D673, { 0x0064, 0x0000, 0x0000, 0x0000 } }, - { 0x1D674, { 0x0065, 0x0000, 0x0000, 0x0000 } }, - { 0x1D675, { 0x0066, 0x0000, 0x0000, 0x0000 } }, - { 0x1D676, { 0x0067, 0x0000, 0x0000, 0x0000 } }, - { 0x1D677, { 0x0068, 0x0000, 0x0000, 0x0000 } }, - { 0x1D678, { 0x0069, 0x0000, 0x0000, 0x0000 } }, - { 0x1D679, { 0x006A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67A, { 0x006B, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67B, { 0x006C, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67C, { 0x006D, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67D, { 0x006E, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67E, { 0x006F, 0x0000, 0x0000, 0x0000 } }, - { 0x1D67F, { 0x0070, 0x0000, 0x0000, 0x0000 } }, - { 0x1D680, { 0x0071, 0x0000, 0x0000, 0x0000 } }, - { 0x1D681, { 0x0072, 0x0000, 0x0000, 0x0000 } }, - { 0x1D682, { 0x0073, 0x0000, 0x0000, 0x0000 } }, - { 0x1D683, { 0x0074, 0x0000, 0x0000, 0x0000 } }, - { 0x1D684, { 0x0075, 0x0000, 0x0000, 0x0000 } }, - { 0x1D685, { 0x0076, 0x0000, 0x0000, 0x0000 } }, - { 0x1D686, { 0x0077, 0x0000, 0x0000, 0x0000 } }, - { 0x1D687, { 0x0078, 0x0000, 0x0000, 0x0000 } }, - { 0x1D688, { 0x0079, 0x0000, 0x0000, 0x0000 } }, - { 0x1D689, { 0x007A, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6A8, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6A9, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AA, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AB, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AC, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AD, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AE, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6AF, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B0, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B1, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B2, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B3, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B4, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B5, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B6, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B7, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B8, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6B9, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BA, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BB, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BC, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BD, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BE, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6BF, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6C0, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6D3, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E2, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E3, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E4, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E5, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E6, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E7, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E8, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6E9, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6EA, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6EB, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6EC, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6ED, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6EE, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6EF, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F0, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F1, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F2, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F3, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F4, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F5, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F6, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F7, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F8, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6F9, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D6FA, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D70D, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D71C, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D71D, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x1D71E, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D71F, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D720, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D721, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D722, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D723, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D724, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D725, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x1D726, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x1D727, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x1D728, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x1D729, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72A, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72B, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72C, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72D, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72E, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D72F, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D730, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D731, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D732, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D733, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D734, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D747, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D756, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D757, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x1D758, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D759, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75A, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75B, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75C, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75D, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75E, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D75F, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x1D760, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x1D761, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x1D762, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x1D763, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x1D764, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x1D765, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x1D766, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D767, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D768, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D769, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D76A, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D76B, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D76C, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D76D, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D76E, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D781, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D790, { 0x03B1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D791, { 0x03B2, 0x0000, 0x0000, 0x0000 } }, - { 0x1D792, { 0x03B3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D793, { 0x03B4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D794, { 0x03B5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D795, { 0x03B6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D796, { 0x03B7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D797, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D798, { 0x03B9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D799, { 0x03BA, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79A, { 0x03BB, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79B, { 0x03BC, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79C, { 0x03BD, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79D, { 0x03BE, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79E, { 0x03BF, 0x0000, 0x0000, 0x0000 } }, - { 0x1D79F, { 0x03C0, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A0, { 0x03C1, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A1, { 0x03B8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A2, { 0x03C3, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A3, { 0x03C4, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A4, { 0x03C5, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A5, { 0x03C6, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A6, { 0x03C7, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A7, { 0x03C8, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7A8, { 0x03C9, 0x0000, 0x0000, 0x0000 } }, - { 0x1D7BB, { 0x03C3, 0x0000, 0x0000, 0x0000 } } -}; - -static void mapToLowerCase(QString *str, int from) -{ - ushort *d = nullptr; - for (int i = from; i < str->size(); ++i) { - uint uc = str->at(i).unicode(); - if (uc < 0x80) { - if (uc <= 'Z' && uc >= 'A') { - if (!d) - d = reinterpret_cast(str->data()); - d[i] = (uc | 0x20); - } - } else { - if (QChar(uc).isHighSurrogate() && i < str->size() - 1) { - ushort low = str->at(i + 1).unicode(); - if (QChar(low).isLowSurrogate()) { - uc = QChar::surrogateToUcs4(uc, low); - ++i; - } - } - const auto entry = std::lower_bound(std::begin(NameprepCaseFolding), - std::end(NameprepCaseFolding), - uc); - if ((entry != std::end(NameprepCaseFolding)) && !(uc < *entry)) { - int l = 1; - while (l < 4 && entry->mapping[l]) - ++l; - if (l > 1 || uc > 0xffff) { - if (uc <= 0xffff) - str->replace(i, 1, reinterpret_cast(&entry->mapping[0]), l); - else - str->replace(--i, 2, reinterpret_cast(&entry->mapping[0]), l); - i += l - 1; - d = nullptr; - } else { - if (!d) - d = reinterpret_cast(str->data()); - d[i] = entry->mapping[0]; - } - } - } - } -} - -static bool isMappedToNothing(uint uc) -{ - if (uc < 0xad) - return false; - switch (uc) { - case 0x00AD: case 0x034F: case 0x1806: case 0x180B: case 0x180C: case 0x180D: - case 0x200B: case 0x200C: case 0x200D: case 0x2060: case 0xFE00: case 0xFE01: - case 0xFE02: case 0xFE03: case 0xFE04: case 0xFE05: case 0xFE06: case 0xFE07: - case 0xFE08: case 0xFE09: case 0xFE0A: case 0xFE0B: case 0xFE0C: case 0xFE0D: - case 0xFE0E: case 0xFE0F: case 0xFEFF: - return true; - default: - return false; - } -} - -namespace { - static constexpr bool isProhibitedOutputChar(char32_t uc) - { - if (uc <= 0xFFFF) { - if (uc < 0x80 || - !(uc <= 0x009F - || uc == 0x00A0 - || uc == 0x0340 - || uc == 0x0341 - || uc == 0x06DD - || uc == 0x070F - || uc == 0x1680 - || uc == 0x180E - || (uc >= 0x2000 && uc <= 0x200F) - || (uc >= 0x2028 && uc <= 0x202F) - || uc == 0x205F - || (uc >= 0x2060 && uc <= 0x2063) - || (uc >= 0x206A && uc <= 0x206F) - || (uc >= 0x2FF0 && uc <= 0x2FFB) - || uc == 0x3000 - || (uc >= 0xD800 && uc <= 0xDFFF) - || (uc >= 0xE000 && uc <= 0xF8FF) - || (uc >= 0xFDD0 && uc <= 0xFDEF) - || uc == 0xFEFF - || uc >= 0xFFF9)) { - return false; - } - } else { - if (!((uc >= 0x1D173 && uc <= 0x1D17A) - || (uc >= 0x1FFFE && uc <= 0x1FFFF) - || (uc >= 0x2FFFE && uc <= 0x2FFFF) - || (uc >= 0x3FFFE && uc <= 0x3FFFF) - || (uc >= 0x4FFFE && uc <= 0x4FFFF) - || (uc >= 0x5FFFE && uc <= 0x5FFFF) - || (uc >= 0x6FFFE && uc <= 0x6FFFF) - || (uc >= 0x7FFFE && uc <= 0x7FFFF) - || (uc >= 0x8FFFE && uc <= 0x8FFFF) - || (uc >= 0x9FFFE && uc <= 0x9FFFF) - || (uc >= 0xAFFFE && uc <= 0xAFFFF) - || (uc >= 0xBFFFE && uc <= 0xBFFFF) - || (uc >= 0xCFFFE && uc <= 0xCFFFF) - || (uc >= 0xDFFFE && uc <= 0xDFFFF) - || uc == 0xE0001 - || (uc >= 0xE0020 && uc <= 0xE007F) - || (uc >= 0xEFFFE && uc <= 0xEFFFF) - || (uc >= 0xF0000 && uc <= 0xFFFFD) - || (uc >= 0xFFFFE && uc <= 0xFFFFF) - || (uc >= 0x100000 && uc <= 0x10FFFD) - || (uc >= 0x10FFFE && uc <= 0x10FFFF))) { - return false; - } - } - return true; - } -} // unnamed namespace - -static bool containsProhibitedOutput(QStringView str, qsizetype from) -{ - constexpr char32_t invalid = 0xDEAD; - static_assert(isProhibitedOutputChar(invalid)); - - QStringIterator it{str, from}; - while (it.hasNext()) { - if (isProhibitedOutputChar(it.next(invalid))) - return true; - } - - return false; -} - -static bool isBidirectionalRorAL(uint uc) -{ - if (uc < 0x5b0) - return false; - return uc == 0x05BE - || uc == 0x05C0 - || uc == 0x05C3 - || (uc >= 0x05D0 && uc <= 0x05EA) - || (uc >= 0x05F0 && uc <= 0x05F4) - || uc == 0x061B - || uc == 0x061F - || (uc >= 0x0621 && uc <= 0x063A) - || (uc >= 0x0640 && uc <= 0x064A) - || (uc >= 0x066D && uc <= 0x066F) - || (uc >= 0x0671 && uc <= 0x06D5) - || uc == 0x06DD - || (uc >= 0x06E5 && uc <= 0x06E6) - || (uc >= 0x06FA && uc <= 0x06FE) - || (uc >= 0x0700 && uc <= 0x070D) - || uc == 0x0710 - || (uc >= 0x0712 && uc <= 0x072C) - || (uc >= 0x0780 && uc <= 0x07A5) - || uc == 0x07B1 - || uc == 0x200F - || uc == 0xFB1D - || (uc >= 0xFB1F && uc <= 0xFB28) - || (uc >= 0xFB2A && uc <= 0xFB36) - || (uc >= 0xFB38 && uc <= 0xFB3C) - || uc == 0xFB3E - || (uc >= 0xFB40 && uc <= 0xFB41) - || (uc >= 0xFB43 && uc <= 0xFB44) - || (uc >= 0xFB46 && uc <= 0xFBB1) - || (uc >= 0xFBD3 && uc <= 0xFD3D) - || (uc >= 0xFD50 && uc <= 0xFD8F) - || (uc >= 0xFD92 && uc <= 0xFDC7) - || (uc >= 0xFDF0 && uc <= 0xFDFC) - || (uc >= 0xFE70 && uc <= 0xFE74) - || (uc >= 0xFE76 && uc <= 0xFEFC); -} - -static bool isBidirectionalL(uint uc) -{ - if (uc < 0xaa) - return (uc >= 0x0041 && uc <= 0x005A) - || (uc >= 0x0061 && uc <= 0x007A); - - if (uc == 0x00AA - || uc == 0x00B5 - || uc == 0x00BA - || (uc >= 0x00C0 && uc <= 0x00D6) - || (uc >= 0x00D8 && uc <= 0x00F6) - || (uc >= 0x00F8 && uc <= 0x0220) - || (uc >= 0x0222 && uc <= 0x0233) - || (uc >= 0x0250 && uc <= 0x02AD) - || (uc >= 0x02B0 && uc <= 0x02B8) - || (uc >= 0x02BB && uc <= 0x02C1) - || (uc >= 0x02D0 && uc <= 0x02D1) - || (uc >= 0x02E0 && uc <= 0x02E4) - || uc == 0x02EE - || uc == 0x037A - || uc == 0x0386 - || (uc >= 0x0388 && uc <= 0x038A)) { - return true; - } - - if (uc == 0x038C - || (uc >= 0x038E && uc <= 0x03A1) - || (uc >= 0x03A3 && uc <= 0x03CE) - || (uc >= 0x03D0 && uc <= 0x03F5) - || (uc >= 0x0400 && uc <= 0x0482) - || (uc >= 0x048A && uc <= 0x04CE) - || (uc >= 0x04D0 && uc <= 0x04F5) - || (uc >= 0x04F8 && uc <= 0x04F9) - || (uc >= 0x0500 && uc <= 0x050F) - || (uc >= 0x0531 && uc <= 0x0556) - || (uc >= 0x0559 && uc <= 0x055F) - || (uc >= 0x0561 && uc <= 0x0587) - || uc == 0x0589 - || uc == 0x0903 - || (uc >= 0x0905 && uc <= 0x0939) - || (uc >= 0x093D && uc <= 0x0940) - || (uc >= 0x0949 && uc <= 0x094C) - || uc == 0x0950) { - return true; - } - - if ((uc >= 0x0958 && uc <= 0x0961) - || (uc >= 0x0964 && uc <= 0x0970) - || (uc >= 0x0982 && uc <= 0x0983) - || (uc >= 0x0985 && uc <= 0x098C) - || (uc >= 0x098F && uc <= 0x0990) - || (uc >= 0x0993 && uc <= 0x09A8) - || (uc >= 0x09AA && uc <= 0x09B0) - || uc == 0x09B2 - || (uc >= 0x09B6 && uc <= 0x09B9) - || (uc >= 0x09BE && uc <= 0x09C0) - || (uc >= 0x09C7 && uc <= 0x09C8) - || (uc >= 0x09CB && uc <= 0x09CC) - || uc == 0x09D7 - || (uc >= 0x09DC && uc <= 0x09DD) - || (uc >= 0x09DF && uc <= 0x09E1) - || (uc >= 0x09E6 && uc <= 0x09F1) - || (uc >= 0x09F4 && uc <= 0x09FA) - || (uc >= 0x0A05 && uc <= 0x0A0A) - || (uc >= 0x0A0F && uc <= 0x0A10) - || (uc >= 0x0A13 && uc <= 0x0A28) - || (uc >= 0x0A2A && uc <= 0x0A30) - || (uc >= 0x0A32 && uc <= 0x0A33)) { - return true; - } - - if ((uc >= 0x0A35 && uc <= 0x0A36) - || (uc >= 0x0A38 && uc <= 0x0A39) - || (uc >= 0x0A3E && uc <= 0x0A40) - || (uc >= 0x0A59 && uc <= 0x0A5C) - || uc == 0x0A5E - || (uc >= 0x0A66 && uc <= 0x0A6F) - || (uc >= 0x0A72 && uc <= 0x0A74) - || uc == 0x0A83 - || (uc >= 0x0A85 && uc <= 0x0A8B) - || uc == 0x0A8D - || (uc >= 0x0A8F && uc <= 0x0A91) - || (uc >= 0x0A93 && uc <= 0x0AA8) - || (uc >= 0x0AAA && uc <= 0x0AB0) - || (uc >= 0x0AB2 && uc <= 0x0AB3) - || (uc >= 0x0AB5 && uc <= 0x0AB9) - || (uc >= 0x0ABD && uc <= 0x0AC0) - || uc == 0x0AC9 - || (uc >= 0x0ACB && uc <= 0x0ACC) - || uc == 0x0AD0 - || uc == 0x0AE0 - || (uc >= 0x0AE6 && uc <= 0x0AEF) - || (uc >= 0x0B02 && uc <= 0x0B03) - || (uc >= 0x0B05 && uc <= 0x0B0C) - || (uc >= 0x0B0F && uc <= 0x0B10) - || (uc >= 0x0B13 && uc <= 0x0B28) - || (uc >= 0x0B2A && uc <= 0x0B30)) { - return true; - } - - if ((uc >= 0x0B32 && uc <= 0x0B33) - || (uc >= 0x0B36 && uc <= 0x0B39) - || (uc >= 0x0B3D && uc <= 0x0B3E) - || uc == 0x0B40 - || (uc >= 0x0B47 && uc <= 0x0B48) - || (uc >= 0x0B4B && uc <= 0x0B4C) - || uc == 0x0B57 - || (uc >= 0x0B5C && uc <= 0x0B5D) - || (uc >= 0x0B5F && uc <= 0x0B61) - || (uc >= 0x0B66 && uc <= 0x0B70) - || uc == 0x0B83 - || (uc >= 0x0B85 && uc <= 0x0B8A) - || (uc >= 0x0B8E && uc <= 0x0B90) - || (uc >= 0x0B92 && uc <= 0x0B95) - || (uc >= 0x0B99 && uc <= 0x0B9A) - || uc == 0x0B9C - || (uc >= 0x0B9E && uc <= 0x0B9F) - || (uc >= 0x0BA3 && uc <= 0x0BA4) - || (uc >= 0x0BA8 && uc <= 0x0BAA) - || (uc >= 0x0BAE && uc <= 0x0BB5) - || (uc >= 0x0BB7 && uc <= 0x0BB9) - || (uc >= 0x0BBE && uc <= 0x0BBF) - || (uc >= 0x0BC1 && uc <= 0x0BC2) - || (uc >= 0x0BC6 && uc <= 0x0BC8) - || (uc >= 0x0BCA && uc <= 0x0BCC) - || uc == 0x0BD7 - || (uc >= 0x0BE7 && uc <= 0x0BF2) - || (uc >= 0x0C01 && uc <= 0x0C03) - || (uc >= 0x0C05 && uc <= 0x0C0C) - || (uc >= 0x0C0E && uc <= 0x0C10) - || (uc >= 0x0C12 && uc <= 0x0C28) - || (uc >= 0x0C2A && uc <= 0x0C33) - || (uc >= 0x0C35 && uc <= 0x0C39)) { - return true; - } - if ((uc >= 0x0C41 && uc <= 0x0C44) - || (uc >= 0x0C60 && uc <= 0x0C61) - || (uc >= 0x0C66 && uc <= 0x0C6F) - || (uc >= 0x0C82 && uc <= 0x0C83) - || (uc >= 0x0C85 && uc <= 0x0C8C) - || (uc >= 0x0C8E && uc <= 0x0C90) - || (uc >= 0x0C92 && uc <= 0x0CA8) - || (uc >= 0x0CAA && uc <= 0x0CB3) - || (uc >= 0x0CB5 && uc <= 0x0CB9) - || uc == 0x0CBE - || (uc >= 0x0CC0 && uc <= 0x0CC4) - || (uc >= 0x0CC7 && uc <= 0x0CC8) - || (uc >= 0x0CCA && uc <= 0x0CCB) - || (uc >= 0x0CD5 && uc <= 0x0CD6) - || uc == 0x0CDE - || (uc >= 0x0CE0 && uc <= 0x0CE1) - || (uc >= 0x0CE6 && uc <= 0x0CEF) - || (uc >= 0x0D02 && uc <= 0x0D03) - || (uc >= 0x0D05 && uc <= 0x0D0C) - || (uc >= 0x0D0E && uc <= 0x0D10) - || (uc >= 0x0D12 && uc <= 0x0D28) - || (uc >= 0x0D2A && uc <= 0x0D39) - || (uc >= 0x0D3E && uc <= 0x0D40) - || (uc >= 0x0D46 && uc <= 0x0D48) - || (uc >= 0x0D4A && uc <= 0x0D4C) - || uc == 0x0D57 - || (uc >= 0x0D60 && uc <= 0x0D61) - || (uc >= 0x0D66 && uc <= 0x0D6F) - || (uc >= 0x0D82 && uc <= 0x0D83) - || (uc >= 0x0D85 && uc <= 0x0D96) - || (uc >= 0x0D9A && uc <= 0x0DB1) - || (uc >= 0x0DB3 && uc <= 0x0DBB) - || uc == 0x0DBD) { - return true; - } - if ((uc >= 0x0DC0 && uc <= 0x0DC6) - || (uc >= 0x0DCF && uc <= 0x0DD1) - || (uc >= 0x0DD8 && uc <= 0x0DDF) - || (uc >= 0x0DF2 && uc <= 0x0DF4) - || (uc >= 0x0E01 && uc <= 0x0E30) - || (uc >= 0x0E32 && uc <= 0x0E33) - || (uc >= 0x0E40 && uc <= 0x0E46) - || (uc >= 0x0E4F && uc <= 0x0E5B) - || (uc >= 0x0E81 && uc <= 0x0E82) - || uc == 0x0E84 - || (uc >= 0x0E87 && uc <= 0x0E88) - || uc == 0x0E8A - || uc == 0x0E8D - || (uc >= 0x0E94 && uc <= 0x0E97) - || (uc >= 0x0E99 && uc <= 0x0E9F) - || (uc >= 0x0EA1 && uc <= 0x0EA3) - || uc == 0x0EA5 - || uc == 0x0EA7 - || (uc >= 0x0EAA && uc <= 0x0EAB) - || (uc >= 0x0EAD && uc <= 0x0EB0) - || (uc >= 0x0EB2 && uc <= 0x0EB3) - || uc == 0x0EBD - || (uc >= 0x0EC0 && uc <= 0x0EC4) - || uc == 0x0EC6 - || (uc >= 0x0ED0 && uc <= 0x0ED9) - || (uc >= 0x0EDC && uc <= 0x0EDD) - || (uc >= 0x0F00 && uc <= 0x0F17) - || (uc >= 0x0F1A && uc <= 0x0F34) - || uc == 0x0F36 - || uc == 0x0F38 - || (uc >= 0x0F3E && uc <= 0x0F47) - || (uc >= 0x0F49 && uc <= 0x0F6A) - || uc == 0x0F7F - || uc == 0x0F85 - || (uc >= 0x0F88 && uc <= 0x0F8B) - || (uc >= 0x0FBE && uc <= 0x0FC5) - || (uc >= 0x0FC7 && uc <= 0x0FCC) - || uc == 0x0FCF) { - return true; - } - - if ((uc >= 0x1000 && uc <= 0x1021) - || (uc >= 0x1023 && uc <= 0x1027) - || (uc >= 0x1029 && uc <= 0x102A) - || uc == 0x102C - || uc == 0x1031 - || uc == 0x1038 - || (uc >= 0x1040 && uc <= 0x1057) - || (uc >= 0x10A0 && uc <= 0x10C5) - || (uc >= 0x10D0 && uc <= 0x10F8) - || uc == 0x10FB - || (uc >= 0x1100 && uc <= 0x1159) - || (uc >= 0x115F && uc <= 0x11A2) - || (uc >= 0x11A8 && uc <= 0x11F9) - || (uc >= 0x1200 && uc <= 0x1206) - || (uc >= 0x1208 && uc <= 0x1246) - || uc == 0x1248 - || (uc >= 0x124A && uc <= 0x124D) - || (uc >= 0x1250 && uc <= 0x1256) - || uc == 0x1258 - || (uc >= 0x125A && uc <= 0x125D) - || (uc >= 0x1260 && uc <= 0x1286) - || uc == 0x1288 - || (uc >= 0x128A && uc <= 0x128D) - || (uc >= 0x1290 && uc <= 0x12AE) - || uc == 0x12B0 - || (uc >= 0x12B2 && uc <= 0x12B5) - || (uc >= 0x12B8 && uc <= 0x12BE) - || uc == 0x12C0 - || (uc >= 0x12C2 && uc <= 0x12C5) - || (uc >= 0x12C8 && uc <= 0x12CE) - || (uc >= 0x12D0 && uc <= 0x12D6) - || (uc >= 0x12D8 && uc <= 0x12EE) - || (uc >= 0x12F0 && uc <= 0x130E) - || uc == 0x1310) { - return true; - } - - if ((uc >= 0x1312 && uc <= 0x1315) - || (uc >= 0x1318 && uc <= 0x131E) - || (uc >= 0x1320 && uc <= 0x1346) - || (uc >= 0x1348 && uc <= 0x135A) - || (uc >= 0x1361 && uc <= 0x137C) - || (uc >= 0x13A0 && uc <= 0x13F4) - || (uc >= 0x1401 && uc <= 0x1676) - || (uc >= 0x1681 && uc <= 0x169A) - || (uc >= 0x16A0 && uc <= 0x16F0) - || (uc >= 0x1700 && uc <= 0x170C) - || (uc >= 0x170E && uc <= 0x1711) - || (uc >= 0x1720 && uc <= 0x1731) - || (uc >= 0x1735 && uc <= 0x1736) - || (uc >= 0x1740 && uc <= 0x1751) - || (uc >= 0x1760 && uc <= 0x176C) - || (uc >= 0x176E && uc <= 0x1770) - || (uc >= 0x1780 && uc <= 0x17B6) - || (uc >= 0x17BE && uc <= 0x17C5) - || (uc >= 0x17C7 && uc <= 0x17C8) - || (uc >= 0x17D4 && uc <= 0x17DA) - || uc == 0x17DC - || (uc >= 0x17E0 && uc <= 0x17E9) - || (uc >= 0x1810 && uc <= 0x1819) - || (uc >= 0x1820 && uc <= 0x1877) - || (uc >= 0x1880 && uc <= 0x18A8) - || (uc >= 0x1E00 && uc <= 0x1E9B) - || (uc >= 0x1EA0 && uc <= 0x1EF9) - || (uc >= 0x1F00 && uc <= 0x1F15) - || (uc >= 0x1F18 && uc <= 0x1F1D) - || (uc >= 0x1F20 && uc <= 0x1F45) - || (uc >= 0x1F48 && uc <= 0x1F4D) - || (uc >= 0x1F50 && uc <= 0x1F57) - || uc == 0x1F59 - || uc == 0x1F5B - || uc == 0x1F5D) { - return true; - } - - if ((uc >= 0x1F5F && uc <= 0x1F7D) - || (uc >= 0x1F80 && uc <= 0x1FB4) - || (uc >= 0x1FB6 && uc <= 0x1FBC) - || uc == 0x1FBE - || (uc >= 0x1FC2 && uc <= 0x1FC4) - || (uc >= 0x1FC6 && uc <= 0x1FCC) - || (uc >= 0x1FD0 && uc <= 0x1FD3) - || (uc >= 0x1FD6 && uc <= 0x1FDB) - || (uc >= 0x1FE0 && uc <= 0x1FEC) - || (uc >= 0x1FF2 && uc <= 0x1FF4) - || (uc >= 0x1FF6 && uc <= 0x1FFC) - || uc == 0x200E - || uc == 0x2071 - || uc == 0x207F - || uc == 0x2102 - || uc == 0x2107 - || (uc >= 0x210A && uc <= 0x2113) - || uc == 0x2115 - || (uc >= 0x2119 && uc <= 0x211D)) { - return true; - } - - if (uc == 0x2124 - || uc == 0x2126 - || uc == 0x2128 - || (uc >= 0x212A && uc <= 0x212D) - || (uc >= 0x212F && uc <= 0x2131) - || (uc >= 0x2133 && uc <= 0x2139) - || (uc >= 0x213D && uc <= 0x213F) - || (uc >= 0x2145 && uc <= 0x2149) - || (uc >= 0x2160 && uc <= 0x2183) - || (uc >= 0x2336 && uc <= 0x237A) - || uc == 0x2395 - || (uc >= 0x249C && uc <= 0x24E9) - || (uc >= 0x3005 && uc <= 0x3007) - || (uc >= 0x3021 && uc <= 0x3029) - || (uc >= 0x3031 && uc <= 0x3035) - || (uc >= 0x3038 && uc <= 0x303C) - || (uc >= 0x3041 && uc <= 0x3096) - || (uc >= 0x309D && uc <= 0x309F) - || (uc >= 0x30A1 && uc <= 0x30FA)) { - return true; - } - - if ((uc >= 0x30FC && uc <= 0x30FF) - || (uc >= 0x3105 && uc <= 0x312C) - || (uc >= 0x3131 && uc <= 0x318E) - || (uc >= 0x3190 && uc <= 0x31B7) - || (uc >= 0x31F0 && uc <= 0x321C) - || (uc >= 0x3220 && uc <= 0x3243)) { - return true; - } - - if ((uc >= 0x3260 && uc <= 0x327B) - || (uc >= 0x327F && uc <= 0x32B0) - || (uc >= 0x32C0 && uc <= 0x32CB) - || (uc >= 0x32D0 && uc <= 0x32FE) - || (uc >= 0x3300 && uc <= 0x3376) - || (uc >= 0x337B && uc <= 0x33DD)) { - return true; - } - if ((uc >= 0x33E0 && uc <= 0x33FE) - || (uc >= 0x3400 && uc <= 0x4DB5) - || (uc >= 0x4E00 && uc <= 0x9FA5) - || (uc >= 0xA000 && uc <= 0xA48C) - || (uc >= 0xAC00 && uc <= 0xD7A3) - || (uc >= 0xD800 && uc <= 0xFA2D) - || (uc >= 0xFA30 && uc <= 0xFA6A) - || (uc >= 0xFB00 && uc <= 0xFB06) - || (uc >= 0xFB13 && uc <= 0xFB17) - || (uc >= 0xFF21 && uc <= 0xFF3A) - || (uc >= 0xFF41 && uc <= 0xFF5A) - || (uc >= 0xFF66 && uc <= 0xFFBE) - || (uc >= 0xFFC2 && uc <= 0xFFC7) - || (uc >= 0xFFCA && uc <= 0xFFCF) - || (uc >= 0xFFD2 && uc <= 0xFFD7) - || (uc >= 0xFFDA && uc <= 0xFFDC)) { - return true; - } - - if ((uc >= 0x10300 && uc <= 0x1031E) - || (uc >= 0x10320 && uc <= 0x10323) - || (uc >= 0x10330 && uc <= 0x1034A) - || (uc >= 0x10400 && uc <= 0x10425) - || (uc >= 0x10428 && uc <= 0x1044D) - || (uc >= 0x1D000 && uc <= 0x1D0F5) - || (uc >= 0x1D100 && uc <= 0x1D126) - || (uc >= 0x1D12A && uc <= 0x1D166) - || (uc >= 0x1D16A && uc <= 0x1D172) - || (uc >= 0x1D183 && uc <= 0x1D184) - || (uc >= 0x1D18C && uc <= 0x1D1A9) - || (uc >= 0x1D1AE && uc <= 0x1D1DD) - || (uc >= 0x1D400 && uc <= 0x1D454) - || (uc >= 0x1D456 && uc <= 0x1D49C) - || (uc >= 0x1D49E && uc <= 0x1D49F) - || uc == 0x1D4A2 - || (uc >= 0x1D4A5 && uc <= 0x1D4A6) - || (uc >= 0x1D4A9 && uc <= 0x1D4AC) - || (uc >= 0x1D4AE && uc <= 0x1D4B9) - || uc == 0x1D4BB - || (uc >= 0x1D4BD && uc <= 0x1D4C0) - || (uc >= 0x1D4C2 && uc <= 0x1D4C3) - || (uc >= 0x1D4C5 && uc <= 0x1D505) - || (uc >= 0x1D507 && uc <= 0x1D50A) - || (uc >= 0x1D50D && uc <= 0x1D514) - || (uc >= 0x1D516 && uc <= 0x1D51C) - || (uc >= 0x1D51E && uc <= 0x1D539) - || (uc >= 0x1D53B && uc <= 0x1D53E) - || (uc >= 0x1D540 && uc <= 0x1D544) - || uc == 0x1D546 - || (uc >= 0x1D54A && uc <= 0x1D550) - || (uc >= 0x1D552 && uc <= 0x1D6A3) - || (uc >= 0x1D6A8 && uc <= 0x1D7C9) - || (uc >= 0x20000 && uc <= 0x2A6D6) - || (uc >= 0x2F800 && uc <= 0x2FA1D) - || (uc >= 0xF0000 && uc <= 0xFFFFD) - || (uc >= 0x100000 && uc <= 0x10FFFD)) { - return true; - } - - return false; -} - -static bool qt_nameprep(QString *source, int from) -{ - QChar *src = source->data(); // causes a detach, so we're sure the only one using it - QChar *out = src + from; - const QChar *e = src + source->size(); - - for ( ; out < e; ++out) { - ushort uc = out->unicode(); - if (uc >= 0x80) { - break; - } else if (uc >= 'A' && uc <= 'Z') { - *out = QChar(uc | 0x20); - } - } - if (out == e) - return true; // everything was mapped easily (lowercased, actually) - int firstNonAscii = out - src; - - // Characters unassigned in Unicode 3.2 are not allowed in "stored string" scheme - // but allowed in "query" scheme - // (Table A.1) - const bool isUnassignedAllowed = false; // ### - // Characters commonly mapped to nothing are simply removed - // (Table B.1) - const QChar *in = out; - for ( ; in < e; ++in) { - uint uc = in->unicode(); - if (QChar(uc).isHighSurrogate() && in < e - 1) { - ushort low = in[1].unicode(); - if (QChar(low).isLowSurrogate()) { - ++in; - uc = QChar::surrogateToUcs4(uc, low); - } - } - if (!isUnassignedAllowed) { - QChar::UnicodeVersion version = QChar::unicodeVersion(uc); - if (version == QChar::Unicode_Unassigned || version > QChar::Unicode_3_2) { - source->resize(from); // not allowed, clear the label - return false; - } - } - if (!isMappedToNothing(uc)) { - if (uc <= 0xFFFF) { - *out++ = *in; - } else { - *out++ = in[-1]; - *out++ = in[0]; - } - } - } - if (out != in) - source->truncate(out - src); - - // Map to lowercase (Table B.2) - mapToLowerCase(source, firstNonAscii); - - // Normalize to Unicode 3.2 form KC - extern void qt_string_normalize(QString *data, QString::NormalizationForm mode, - QChar::UnicodeVersion version, qsizetype from); - qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2, - firstNonAscii > from ? firstNonAscii - 1 : from); - - // Check for prohibited output - if (containsProhibitedOutput(*source, firstNonAscii)) { - source->resize(from); - return false; - } - - // Check for valid bidirectional characters - bool containsLCat = false; - bool containsRandALCat = false; - src = source->data(); - e = src + source->size(); - for (in = src + from; in < e && (!containsLCat || !containsRandALCat); ++in) { - uint uc = in->unicode(); - if (QChar(uc).isHighSurrogate() && in < e - 1) { - ushort low = in[1].unicode(); - if (QChar(low).isLowSurrogate()) { - ++in; - uc = QChar::surrogateToUcs4(uc, low); - } - } - if (isBidirectionalL(uc)) - containsLCat = true; - else if (isBidirectionalRorAL(uc)) - containsRandALCat = true; - } - if (containsRandALCat) { - if (containsLCat || (!isBidirectionalRorAL(src[from].unicode()) - || !isBidirectionalRorAL(e[-1].unicode()))) { - source->resize(from); // not allowed, clear the label - return false; - } - } - - return true; -} - -static const QChar *qt_find_nonstd3(QStringView in, Qt::CaseSensitivity cs) -{ - const QChar * const uc = in.data(); - const qsizetype len = in.size(); - - if (len > MaxDomainLabelLength) - return uc; - - for (qsizetype i = 0; i < len; ++i) { - const char16_t c = uc[i].unicode(); - if (c == '-' && (i == 0 || i == len - 1)) - return uc + i; - - // verifying the absence of non-LDH is the same as verifying that - // only LDH is present - if (cs == Qt::CaseInsensitive && (c >= 'A' && c <= 'Z')) - continue; - if (c == '-' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') - //underscore is not supposed to be allowed, but other browser accept it (QTBUG-7434) - || c == '_') - continue; - - return uc + i; - } - - return nullptr; -} - -static bool qt_check_std3rules(QStringView in) -{ - return qt_find_nonstd3(in, Qt::CaseInsensitive) == nullptr; -} - -static bool qt_check_nameprepped_std3(QStringView in) -{ - // fast path: check for lowercase ASCII - const QChar *firstNonAscii = qt_find_nonstd3(in, Qt::CaseSensitive); - if (firstNonAscii == nullptr) { - // everything was lowercase ASCII, digits or hyphen - return true; - } - - QString origin = QString::fromRawData(firstNonAscii, in.end() - firstNonAscii); - QString copy = origin; - qt_nameprep(©, 0); - return origin == copy; -} - static inline uint encodeDigit(uint digit) { return digit + 22 + 75 * (digit < 26); @@ -2499,13 +381,13 @@ static bool equal(const QChar *a, int l, const char *b) return l == 0; } -static bool qt_is_idn_enabled(QStringView domain) +static bool qt_is_idn_enabled(QStringView aceDomain) { - const auto idx = domain.lastIndexOf(QLatin1Char('.')); + auto idx = aceDomain.lastIndexOf(QLatin1Char('.')); if (idx == -1) return false; - QString tldString = qt_ACE_do(domain.mid(idx + 1), ToAceOnly, ForbidLeadingDot); + auto tldString = aceDomain.mid(idx + 1); const auto len = tldString.size(); const QChar *tld = tldString.constData(); @@ -2527,139 +409,546 @@ static bool qt_is_idn_enabled(QStringView domain) return equal(tld, len, idn_whitelist[i]); } -static inline bool isDotDelimiter(ushort uc) +template +static inline bool isValidInNormalizedAsciiLabel(C c) { - // IDNA / rfc3490 describes these four delimiters used for - // separating labels in unicode international domain - // names. - return uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61; + return c == u'-' || c == u'_' || (c >= u'0' && c <= u'9') || (c >= u'a' && c <= u'z'); } -static qsizetype nextDotDelimiter(QStringView domain, qsizetype from = 0) +template +static inline bool isValidInNormalizedAsciiName(C c) { - const QChar *b = domain.data(); - const QChar *ch = b + from; - const QChar *e = b + domain.length(); - while (ch < e) { - if (isDotDelimiter(ch->unicode())) + return isValidInNormalizedAsciiLabel(c) || c == u'.'; +} + +/* + Map domain name according to algorithm in UTS #46, 4.1 + + Returns empty string if there are disallowed characters in the input. + + Sets resultIsAscii if the result is known for sure to be all ASCII. +*/ +static QString mapDomainName(const QString &in, QUrl::AceProcessingOptions options, + bool *resultIsAscii) +{ + *resultIsAscii = true; + + // Check if the input is already normalized ASCII first and can be returned as is. + int i = 0; + for (auto c : in) { + if (c.unicode() >= 0x80 || !isValidInNormalizedAsciiName(c)) break; - else - ++ch; + i++; } - return ch - b; + + if (i == in.size()) + return in; + + QString result; + result.reserve(in.size()); + result.append(in.constData(), i); + bool allAscii = true; + + for (QStringIterator iter(QStringView(in).sliced(i)); iter.hasNext();) { + char32_t uc = iter.next(); + + // Fast path for ASCII-only inputs + if (Q_LIKELY(uc < 0x80)) { + if (uc >= U'A' && uc <= U'Z') + uc |= 0x20; // lower-case it + + if (!isValidInNormalizedAsciiName(uc)) + return {}; + + result.append(static_cast(uc)); + continue; + } + allAscii = false; + + QUnicodeTables::IdnaStatus status = QUnicodeTables::idnaStatus(uc); + + if (status == QUnicodeTables::IdnaStatus::Deviation) + status = options.testFlag(QUrl::AceTransitionalProcessing) + ? QUnicodeTables::IdnaStatus::Mapped + : QUnicodeTables::IdnaStatus::Valid; + + switch (status) { + case QUnicodeTables::IdnaStatus::Ignored: + continue; + case QUnicodeTables::IdnaStatus::Valid: + for (auto c : QChar::fromUcs4(uc)) + result.append(c); + break; + case QUnicodeTables::IdnaStatus::Mapped: { + const char16_t *mapping = QUnicodeTables::idnaMapping(uc); + if (mapping != nullptr) + result.append(mapping); + } break; + case QUnicodeTables::IdnaStatus::Disallowed: + return {}; + default: + Q_UNREACHABLE(); + } + } + + *resultIsAscii = allAscii; + return result; } -QString qt_ACE_do(QStringView domain, AceOperation op, AceLeadingDot dot) +/* + Check the rules for an ASCII label. + + Check the size restriction and that the label does not start or end with dashes. + + The label should be nonempty. +*/ +static bool validateAsciiLabel(QStringView label) { - QString result; - if (domain.isEmpty()) - return result; + if (label.length() > MaxDomainLabelLength) + return false; - result.reserve(domain.length()); + if (label.first() == u'-' || label.last() == u'-') + return false; - const bool isIdnEnabled = op == NormalizeAce ? qt_is_idn_enabled(domain) : false; + return std::all_of(label.begin(), label.end(), isValidInNormalizedAsciiLabel); +} + +namespace { + +class DomainValidityChecker +{ + bool domainNameIsBidi = false; + bool hadBidiErrors = false; + + static constexpr char32_t ZWNJ = U'\u200C'; + static constexpr char32_t ZWJ = U'\u200D'; + +public: + DomainValidityChecker() { } + bool checkLabel(const QString &label, QUrl::AceProcessingOptions options); + +private: + static bool checkContextJRules(QStringView label); + static bool checkBidiRules(QStringView label); +}; + +} // anonymous namespace + +/* + Check CONTEXTJ rules accroding to RFC 5892, appendix A.1 & A.2. + + Rule Set for U+200C (ZWNJ): + + False; + + If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; + + If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C + + (Joining_Type:T)*(Joining_Type:{R,D})) Then True; + + Rule Set for U+200D (ZWJ): + + False; + + If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; + +*/ +bool DomainValidityChecker::checkContextJRules(QStringView label) +{ + constexpr unsigned char CombiningClassVirama = 9; + + enum class State { + Initial, + LD_T, // L,D with possible following T* + ZWNJ_T, // ZWNJ with possible following T* + }; + State regexpState = State::Initial; + bool previousIsVirama = false; + + for (QStringIterator iter(label); iter.hasNext();) { + auto ch = iter.next(); + + if (ch == ZWJ) { + if (!previousIsVirama) + return false; + regexpState = State::Initial; + } else if (ch == ZWNJ) { + if (!previousIsVirama && regexpState != State::LD_T) + return false; + regexpState = previousIsVirama ? State::Initial : State::ZWNJ_T; + } else { + switch (QChar::joiningType(ch)) { + case QChar::Joining_Left: + if (regexpState == State::ZWNJ_T) + return false; + regexpState = State::LD_T; + break; + case QChar::Joining_Right: + regexpState = State::Initial; + break; + case QChar::Joining_Dual: + regexpState = State::LD_T; + break; + case QChar::Joining_Transparent: + break; + default: + regexpState = State::Initial; + break; + } + } + + previousIsVirama = QChar::combiningClass(ch) == CombiningClassVirama; + } + + return regexpState != State::ZWNJ_T; +} + +/* + Check if the label conforms to BiDi rule of RFC 5893. + + 1. The first character must be a character with Bidi property L, R, + or AL. If it has the R or AL property, it is an RTL label; if it + has the L property, it is an LTR label. + + 2. In an RTL label, only characters with the Bidi properties R, AL, + AN, EN, ES, CS, ET, ON, BN, or NSM are allowed. + + 3. In an RTL label, the end of the label must be a character with + Bidi property R, AL, EN, or AN, followed by zero or more + characters with Bidi property NSM. + + 4. In an RTL label, if an EN is present, no AN may be present, and + vice versa. + + 5. In an LTR label, only characters with the Bidi properties L, EN, + ES, CS, ET, ON, BN, or NSM are allowed. + + 6. In an LTR label, the end of the label must be a character with + Bidi property L or EN, followed by zero or more characters with + Bidi property NSM. +*/ +bool DomainValidityChecker::checkBidiRules(QStringView label) +{ + if (label.isEmpty()) + return true; + + QStringIterator iter(label); + Q_ASSERT(iter.hasNext()); + + char32_t ch = iter.next(); + bool labelIsRTL = false; + + switch (QChar::direction(ch)) { + case QChar::DirL: + break; + case QChar::DirR: + case QChar::DirAL: + labelIsRTL = true; + break; + default: + return false; + } + + bool tailOk = true; + bool labelHasEN = false; + bool labelHasAN = false; + + while (iter.hasNext()) { + ch = iter.next(); + + switch (QChar::direction(ch)) { + case QChar::DirR: + case QChar::DirAL: + if (!labelIsRTL) + return false; + tailOk = true; + break; + + case QChar::DirL: + if (labelIsRTL) + return false; + tailOk = true; + break; + + case QChar::DirES: + case QChar::DirCS: + case QChar::DirET: + case QChar::DirON: + case QChar::DirBN: + tailOk = false; + break; + + case QChar::DirNSM: + break; + + case QChar::DirAN: + if (labelIsRTL) { + if (labelHasEN) + return false; + labelHasAN = true; + tailOk = true; + } else { + return false; + } + break; + + case QChar::DirEN: + if (labelIsRTL) { + if (labelHasAN) + return false; + labelHasEN = true; + } + tailOk = true; + break; + + default: + return false; + } + } + + return tailOk; +} + +/* + Check if the given label is valid according to UTS #46 validity criteria. + + NFC check can be skipped if the label was transformed to NFC before calling + this function (as optimization). + + The domain name is considered invalid if this function returns false at least + once. + + 1. The label must be in Unicode Normalization Form NFC. + 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character + in both the third and fourth positions. + 3. If CheckHyphens, the label must neither begin nor end with a U+002D HYPHEN-MINUS character. + 4. The label must not contain a U+002E ( . ) FULL STOP. + 5. The label must not begin with a combining mark, that is: General_Category=Mark. + 6. Each code point in the label must only have certain status values according to Section 5, + IDNA Mapping Table: + 1. For Transitional Processing, each value must be valid. + 2. For Nontransitional Processing, each value must be either valid or deviation. + 7. If CheckJoiners, the label must satisfy the ContextJ rules from Appendix A, in The Unicode + Code Points and Internationalized Domain Names for Applications (IDNA). + 8. If CheckBidi, and if the domain name is a Bidi domain name, then the label must satisfy + all six of the numbered conditions in RFC 5893, Section 2. + + NOTE: Don't use QStringView for label, so that call to QString::normalized() can avoid + memory allocation when there is nothing to normalize. +*/ +bool DomainValidityChecker::checkLabel(const QString &label, QUrl::AceProcessingOptions options) +{ + if (label.isEmpty()) + return true; + + if (label != label.normalized(QString::NormalizationForm_C)) + return false; + + if (label.length() >= 4) { + // This assumes that the first two characters are in BMP, but that's ok + // because non-BMP characters are unlikely to be used for specifying + // future extensions. + if (label[2] == QLatin1Char('-') && label[3] == QLatin1Char('-')) + return false; + } + + if (label.startsWith(QLatin1Char('-')) || label.endsWith(QLatin1Char('-'))) + return false; + + if (label.contains(QLatin1Char('.'))) + return false; + + QStringIterator iter(label); + auto c = iter.next(); + + if (QChar::isMark(c)) + return false; + + // As optimization, CONTEXTJ rules check can be skipped if no + // ZWJ/ZWNJ characters were found during the first pass. + bool hasJoiners = false; + + for (;;) { + hasJoiners = hasJoiners || c == ZWNJ || c == ZWJ; + + if (!domainNameIsBidi) { + switch (QChar::direction(c)) { + case QChar::DirR: + case QChar::DirAL: + case QChar::DirAN: + domainNameIsBidi = true; + if (hadBidiErrors) + return false; + break; + default: + break; + } + } + + switch (QUnicodeTables::idnaStatus(c)) { + case QUnicodeTables::IdnaStatus::Valid: + break; + case QUnicodeTables::IdnaStatus::Deviation: + if (options.testFlag(QUrl::AceTransitionalProcessing)) + return false; + break; + default: + return false; + } + + if (!iter.hasNext()) + break; + c = iter.next(); + } + + if (hasJoiners && !checkContextJRules(label)) + return false; + + hadBidiErrors = hadBidiErrors || !checkBidiRules(label); + + if (domainNameIsBidi && hadBidiErrors) + return false; + + return true; +} + +static QString convertToAscii(const QString &normalizedDomain, AceLeadingDot dot) +{ qsizetype lastIdx = 0; QString aceForm; // this variable is here for caching + QString aceResult; + + while (true) { + auto idx = normalizedDomain.indexOf(u'.', lastIdx); + if (idx == -1) + idx = normalizedDomain.size(); - while (1) { - const auto idx = nextDotDelimiter(domain, lastIdx); const auto labelLength = idx - lastIdx; if (labelLength == 0) { - if (idx == domain.size()) + if (idx == normalizedDomain.size()) break; if (dot == ForbidLeadingDot || idx > 0) - return QString(); // two delimiters in a row -- empty label not allowed - } - - // RFC 3490 says, about the ToASCII operation: - // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: - // - // (a) Verify the absence of non-LDH ASCII code points; that is, the - // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. - // - // (b) Verify the absence of leading and trailing hyphen-minus; that - // is, the absence of U+002D at the beginning and end of the - // sequence. - // and: - // 8. Verify that the number of code points is in the range 1 to 63 - // inclusive. - - // copy the label to the destination, which also serves as our scratch area, lowercasing it - int prevLen = result.size(); - bool simple = true; - result.resize(prevLen + labelLength); - { - QChar *out = result.data() + prevLen; - for (QChar c : domain.mid(lastIdx, labelLength)) { - const auto uc = c.unicode(); - if (uc > 0x7f) - simple = false; - if (uc >= 'A' && uc <= 'Z') - *out++ = QChar(uc | 0x20); - else - *out++ = c; - } - } - - if (simple && labelLength > 6) { - // ACE form domains contain only ASCII characters, but we can't consider them simple - // is this an ACE form? - // the shortest valid ACE domain is 6 characters long (U+0080 would be 1, but it's not allowed) - if (QStringView{result}.sliced(prevLen).startsWith(u"xn--")) - simple = false; - } - - if (simple) { - // fastest case: this is the common case (non IDN-domains) - // so we're done - if (!qt_check_std3rules(QStringView{result.constData() + prevLen, labelLength})) - return QString(); + return {}; // two delimiters in a row -- empty label not allowed } else { - // Punycode encoding and decoding cannot be done in-place - // That means we need one or two temporaries - if (!qt_nameprep(&result, prevLen)) - return QString(); // failed - const auto toReserve = result.length() - prevLen + 4 + 6; // "xn--" plus some extra bytes - aceForm.resize(0); - if (toReserve > aceForm.capacity()) - aceForm.reserve(toReserve); - qt_punycodeEncoder(QStringView{result}.mid(prevLen), &aceForm); + const auto label = QStringView(normalizedDomain).sliced(lastIdx, labelLength); + aceForm.clear(); + qt_punycodeEncoder(label, &aceForm); + if (aceForm.isEmpty()) + return {}; - // We use resize()+memcpy() here because we're overwriting the data we've copied - bool appended = false; - if (isIdnEnabled) { - // The decoding step can fail here if the original domain name contained - // labels that start with "xn--" but don't contain valid Punycode. Even - // if the label was decoded correctly, it may still break some IDNA rules. - // In either case the original ASCII label should be used instead of - // the result returned by the decoder. - QString tmp = qt_punycodeDecoder(aceForm); - if (!tmp.isEmpty() && qt_check_nameprepped_std3(tmp)) { - result.resize(prevLen + tmp.size()); - memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar)); - appended = true; - } - } - - if (!appended) { - result.resize(prevLen + aceForm.size()); - memcpy(result.data() + prevLen, aceForm.constData(), aceForm.size() * sizeof(QChar)); - } - - if (!qt_check_std3rules(aceForm)) - return QString(); + aceResult.append(aceForm); } + if (idx == normalizedDomain.size()) + break; lastIdx = idx + 1; - if (lastIdx < domain.size() + 1) - result += QLatin1Char('.'); - else + aceResult += u'.'; + } + + return aceResult; +} + +static bool checkAsciiDomainName(const QString &normalizedDomain, AceLeadingDot dot, + bool *usesPunycode) +{ + qsizetype lastIdx = 0; + bool hasPunycode = false; + *usesPunycode = false; + + while (lastIdx < normalizedDomain.size()) { + auto idx = normalizedDomain.indexOf(u'.', lastIdx); + if (idx == -1) + idx = normalizedDomain.size(); + + const auto labelLength = idx - lastIdx; + if (labelLength == 0) { + if (idx == normalizedDomain.size()) + break; + if (dot == ForbidLeadingDot || idx > 0) + return false; // two delimiters in a row -- empty label not allowed + } else { + const auto label = QStringView(normalizedDomain).sliced(lastIdx, labelLength); + if (!validateAsciiLabel(label)) + return false; + + hasPunycode = hasPunycode || label.startsWith(QLatin1String("xn--")); + } + + lastIdx = idx + 1; + } + + *usesPunycode = hasPunycode; + return true; +} + +static QString convertToUnicode(const QString &asciiDomain, QUrl::AceProcessingOptions options) +{ + QString result; + result.reserve(asciiDomain.size()); + qsizetype lastIdx = 0; + + DomainValidityChecker checker; + + while (true) { + auto idx = asciiDomain.indexOf(u'.', lastIdx); + if (idx == -1) + idx = asciiDomain.size(); + + const auto labelLength = idx - lastIdx; + if (labelLength == 0) { + if (idx == asciiDomain.size()) + break; + } else { + const auto label = asciiDomain.sliced(lastIdx, labelLength); + const auto unicodeLabel = qt_punycodeDecoder(label); + + if (unicodeLabel.isEmpty()) + return asciiDomain; + + if (!checker.checkLabel(unicodeLabel, options)) + return asciiDomain; + + result.append(unicodeLabel); + } + + if (idx == asciiDomain.size()) break; + + lastIdx = idx + 1; + result += u'.'; } return result; } +QString qt_ACE_do(const QString &domain, AceOperation op, AceLeadingDot dot, + QUrl::AceProcessingOptions options) +{ + if (domain.isEmpty()) + return {}; + + bool mappedToAscii; + const QString mapped = mapDomainName(domain, options, &mappedToAscii); + const QString normalized = + mappedToAscii ? mapped : mapped.normalized(QString::NormalizationForm_C); + + if (normalized.isEmpty()) + return {}; + + bool needsCoversionToUnicode; + const QString aceResult = mappedToAscii ? normalized : convertToAscii(normalized, dot); + if (aceResult.isEmpty() || !checkAsciiDomainName(aceResult, dot, &needsCoversionToUnicode)) + return {}; + + if (op == ToAceOnly || !needsCoversionToUnicode + || (!options.testFlag(QUrl::IgnoreIDNWhitelist) && !qt_is_idn_enabled(aceResult))) { + return aceResult; + } + + return convertToUnicode(aceResult, options); +} + /*! \since 4.2 @@ -2667,6 +956,8 @@ QString qt_ACE_do(QStringView domain, AceOperation op, AceLeadingDot dot) to have non-ASCII characters in their compositions. See setIdnWhitelist() for the rationale of this list. + + \sa AceProcessingOption */ QStringList QUrl::idnWhitelist() {