Merge branch 'v4-0-logon' of git://git.id10ts.net/samba into 4-0-local
authorAndrew Bartlett <abartlet@samba.org>
Wed, 19 Mar 2008 00:04:42 +0000 (11:04 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 19 Mar 2008 00:04:42 +0000 (11:04 +1100)
223 files changed:
source/auth/credentials/credentials.h
source/auth/credentials/credentials_krb5.c
source/auth/credentials/credentials_krb5.h
source/auth/kerberos/kerberos_util.c
source/dsdb/samdb/ldb_modules/samldb.c
source/heimdal/kdc/digest.c
source/heimdal/kdc/kaserver.c
source/heimdal/kdc/kdc_locl.h
source/heimdal/kdc/kerberos5.c
source/heimdal/kdc/krb5tgs.c
source/heimdal/kdc/log.c
source/heimdal/kdc/pkinit.c
source/heimdal/kuser/kinit.c
source/heimdal/lib/asn1/asn1-common.h
source/heimdal/lib/asn1/canthandle.asn1
source/heimdal/lib/asn1/der.c
source/heimdal/lib/asn1/digest.asn1
source/heimdal/lib/asn1/gen.c
source/heimdal/lib/asn1/gen_encode.c
source/heimdal/lib/asn1/k5.asn1
source/heimdal/lib/asn1/lex.c
source/heimdal/lib/asn1/parse.c
source/heimdal/lib/asn1/parse.h
source/heimdal/lib/asn1/pkinit.asn1
source/heimdal/lib/asn1/rfc2459.asn1
source/heimdal/lib/com_err/lex.c
source/heimdal/lib/com_err/parse.c
source/heimdal/lib/com_err/parse.h
source/heimdal/lib/gssapi/gssapi/gssapi_krb5.h
source/heimdal/lib/gssapi/gssapi_mech.h
source/heimdal/lib/gssapi/krb5/acquire_cred.c
source/heimdal/lib/gssapi/krb5/external.c
source/heimdal/lib/gssapi/krb5/gsskrb5-private.h
source/heimdal/lib/gssapi/krb5/gsskrb5_locl.h
source/heimdal/lib/gssapi/krb5/init_sec_context.c
source/heimdal/lib/gssapi/krb5/set_cred_option.c
source/heimdal/lib/gssapi/mech/context.c
source/heimdal/lib/gssapi/mech/gss_accept_sec_context.c
source/heimdal/lib/gssapi/mech/gss_krb5.c
source/heimdal/lib/gssapi/mech/gss_mech_switch.c
source/heimdal/lib/gssapi/mech/gss_release_oid_set.c
source/heimdal/lib/gssapi/spnego/accept_sec_context.c
source/heimdal/lib/gssapi/spnego/compat.c
source/heimdal/lib/gssapi/spnego/context_stubs.c
source/heimdal/lib/gssapi/spnego/external.c
source/heimdal/lib/gssapi/spnego/init_sec_context.c
source/heimdal/lib/gssapi/spnego/spnego-private.h
source/heimdal/lib/hcrypto/bn.c
source/heimdal/lib/hcrypto/bn.h
source/heimdal/lib/hcrypto/camellia-ntt.c [new file with mode: 0644]
source/heimdal/lib/hcrypto/camellia-ntt.h [new file with mode: 0644]
source/heimdal/lib/hcrypto/camellia.c [new file with mode: 0644]
source/heimdal/lib/hcrypto/camellia.h [new file with mode: 0644]
source/heimdal/lib/hcrypto/dh-imath.c
source/heimdal/lib/hcrypto/dh.c
source/heimdal/lib/hcrypto/evp.c
source/heimdal/lib/hcrypto/evp.h
source/heimdal/lib/hcrypto/hmac.c
source/heimdal/lib/hcrypto/imath/imath.c
source/heimdal/lib/hcrypto/rand.c
source/heimdal/lib/hcrypto/rsa.c
source/heimdal/lib/hcrypto/rsa.h
source/heimdal/lib/hdb/dbinfo.c [new file with mode: 0644]
source/heimdal/lib/hdb/hdb-protos.h
source/heimdal/lib/hdb/hdb.h
source/heimdal/lib/hdb/hdb_locl.h
source/heimdal/lib/hdb/keys.c
source/heimdal/lib/hdb/mkey.c
source/heimdal/lib/hx509/ca.c
source/heimdal/lib/hx509/cert.c
source/heimdal/lib/hx509/cms.c
source/heimdal/lib/hx509/crypto.c
source/heimdal/lib/hx509/env.c
source/heimdal/lib/hx509/error.c
source/heimdal/lib/hx509/hx509-private.h
source/heimdal/lib/hx509/hx509-protos.h
source/heimdal/lib/hx509/hx509.h
source/heimdal/lib/hx509/hx509_err.et
source/heimdal/lib/hx509/hx_locl.h
source/heimdal/lib/hx509/keyset.c
source/heimdal/lib/hx509/ks_file.c
source/heimdal/lib/hx509/ks_keychain.c
source/heimdal/lib/hx509/ks_p11.c
source/heimdal/lib/hx509/lock.c
source/heimdal/lib/hx509/name.c
source/heimdal/lib/hx509/peer.c
source/heimdal/lib/hx509/print.c
source/heimdal/lib/hx509/revoke.c
source/heimdal/lib/krb5/acache.c
source/heimdal/lib/krb5/add_et_list.c
source/heimdal/lib/krb5/addr_families.c
source/heimdal/lib/krb5/asn1_glue.c
source/heimdal/lib/krb5/auth_context.c
source/heimdal/lib/krb5/cache.c
source/heimdal/lib/krb5/context.c
source/heimdal/lib/krb5/convert_creds.c
source/heimdal/lib/krb5/copy_host_realm.c
source/heimdal/lib/krb5/creds.c
source/heimdal/lib/krb5/crypto.c
source/heimdal/lib/krb5/data.c
source/heimdal/lib/krb5/eai_to_heim_errno.c
source/heimdal/lib/krb5/error_string.c
source/heimdal/lib/krb5/expand_hostname.c
source/heimdal/lib/krb5/fcache.c
source/heimdal/lib/krb5/get_cred.c
source/heimdal/lib/krb5/get_for_creds.c
source/heimdal/lib/krb5/get_in_tkt.c
source/heimdal/lib/krb5/init_creds.c
source/heimdal/lib/krb5/init_creds_pw.c
source/heimdal/lib/krb5/kcm.c
source/heimdal/lib/krb5/keytab.c
source/heimdal/lib/krb5/keytab_file.c
source/heimdal/lib/krb5/keytab_keyfile.c
source/heimdal/lib/krb5/keytab_krb4.c
source/heimdal/lib/krb5/krb5-private.h
source/heimdal/lib/krb5/krb5-protos.h
source/heimdal/lib/krb5/krb5.h
source/heimdal/lib/krb5/krb5_ccapi.h
source/heimdal/lib/krb5/krb5_locl.h
source/heimdal/lib/krb5/mcache.c
source/heimdal/lib/krb5/n-fold.c
source/heimdal/lib/krb5/pac.c
source/heimdal/lib/krb5/pkinit.c
source/heimdal/lib/krb5/plugin.c
source/heimdal/lib/krb5/principal.c
source/heimdal/lib/krb5/rd_priv.c
source/heimdal/lib/krb5/rd_req.c
source/heimdal/lib/krb5/send_to_kdc.c
source/heimdal/lib/krb5/store.c
source/heimdal/lib/krb5/store_emem.c
source/heimdal/lib/krb5/transited.c
source/heimdal/lib/krb5/v4_glue.c
source/heimdal/lib/ntlm/heimntlm-protos.h
source/heimdal/lib/ntlm/heimntlm.h
source/heimdal/lib/ntlm/ntlm.c
source/heimdal/lib/vers/print_version.c
source/heimdal/lib/wind/bidi.c [new file with mode: 0644]
source/heimdal/lib/wind/bidi_table.c [new file with mode: 0644]
source/heimdal/lib/wind/bidi_table.h [new file with mode: 0644]
source/heimdal/lib/wind/combining.c [new file with mode: 0644]
source/heimdal/lib/wind/combining_table.c [new file with mode: 0644]
source/heimdal/lib/wind/combining_table.h [new file with mode: 0644]
source/heimdal/lib/wind/errorlist.c [new file with mode: 0644]
source/heimdal/lib/wind/errorlist_table.c [new file with mode: 0644]
source/heimdal/lib/wind/errorlist_table.h [new file with mode: 0644]
source/heimdal/lib/wind/ldap.c [new file with mode: 0644]
source/heimdal/lib/wind/map.c [new file with mode: 0644]
source/heimdal/lib/wind/map_table.c [new file with mode: 0644]
source/heimdal/lib/wind/map_table.h [new file with mode: 0644]
source/heimdal/lib/wind/normalize.c [new file with mode: 0644]
source/heimdal/lib/wind/normalize_table.c [new file with mode: 0644]
source/heimdal/lib/wind/normalize_table.h [new file with mode: 0644]
source/heimdal/lib/wind/stringprep.c [new file with mode: 0644]
source/heimdal/lib/wind/utf8.c [new file with mode: 0644]
source/heimdal/lib/wind/wind.h [new file with mode: 0644]
source/heimdal/lib/wind/wind_err.et [new file with mode: 0644]
source/heimdal/lib/wind/windlocl.h [new file with mode: 0644]
source/heimdal_build/config.mk
source/kdc/kdc.c
source/lib/ldb/Makefile.in
source/lib/ldb/common/ldb.c
source/lib/ldb/common/ldb_modules.c
source/lib/ldb/include/ldb_includes.h
source/lib/ldb/include/ldb_private.h
source/lib/ldb/ldb_ldap/ldb_ldap.c
source/lib/ldb/rules.mk
source/lib/ldb/tests/sample_module.c
source/lib/ldb/tests/test-soloading.sh
source/lib/messaging/messaging.c
source/lib/registry/registry_wrap.c
source/lib/replace/README
source/lib/replace/configure.ac
source/lib/replace/getifaddrs.m4
source/lib/replace/getpass.c
source/lib/replace/inet_aton.c [new file with mode: 0644]
source/lib/replace/inet_aton.m4 [new file with mode: 0644]
source/lib/replace/inet_ntoa.c [new file with mode: 0644]
source/lib/replace/inet_ntoa.m4 [new file with mode: 0644]
source/lib/replace/libreplace.m4
source/lib/replace/replace.c
source/lib/replace/replace.h
source/lib/replace/samba.m4
source/lib/replace/snprintf.c
source/lib/replace/socket.m4
source/lib/replace/socketpair.c [new file with mode: 0644]
source/lib/replace/socketpair.m4 [new file with mode: 0644]
source/lib/replace/system/network.h
source/lib/socket/config.m4
source/lib/socket/config.mk
source/lib/socket_wrapper/config.mk
source/lib/socket_wrapper/socket_wrapper.c
source/lib/util/config.mk
source/libcli/security/security_wrap.c
source/libcli/swig/libcli_nbt_wrap.c
source/libcli/util/errors.i
source/libnet/net_wrap.c
source/librpc/config.mk
source/ntvfs/posix/pvfs_open.c
source/ntvfs/posix/pvfs_unlink.c
source/rpc_server/samr/dcesrv_samr.c
source/rpc_server/samr/dcesrv_samr.h
source/script/valgrind_run
source/scripting/python/config.m4
source/scripting/python/config.mk
source/scripting/python/misc_wrap.c
source/scripting/python/samba/provision.py
source/selftest/output/plain.pm
source/selftest/selftest.pl
source/setup/slapd.conf
source/static_deps.mk
source/torture/raw/openbench.c
source/torture/raw/oplock.c
source/torture/rpc/lsa.c
source/torture/rpc/samr.c
source/winbind/config.mk
source/winbind/idmap.c
source/winbind/idmap.h
source/winbind/wb_gid2sid.c
source/winbind/wb_sid2gid.c
source/winbind/wb_sid2uid.c
source/winbind/wb_sids2xids.c [new file with mode: 0644]
source/winbind/wb_uid2sid.c
source/winbind/wb_xids2sids.c [new file with mode: 0644]

index a3da5c60546519889a4e5f6d9ef195415fbff94d..1b205c61ce6f6a806bfc8dc8859ce9fb651e5557 100644 (file)
@@ -128,7 +128,10 @@ struct cli_credentials {
 
 struct ldb_context;
 struct loadparm_context;
-#include "auth/credentials/credentials_krb5.h"
+struct ccache_container;
+
+struct gssapi_creds_container;
+
 #include "auth/credentials/credentials_proto.h"
 
 #endif /* __CREDENTIALS_H__ */
index 90b196e99e3ef312169249188d4e02ec0819e419..52bf9f124feee904c59c21c5299d01544edcd196 100644 (file)
@@ -400,10 +400,10 @@ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
    to the credentials system.
 */
 
-int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, 
-                                        struct loadparm_context *lp_ctx,
-                                        gss_cred_id_t gssapi_cred,
-                                        enum credentials_obtained obtained) 
+ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, 
+                                         struct loadparm_context *lp_ctx,
+                                         gss_cred_id_t gssapi_cred,
+                                         enum credentials_obtained obtained) 
 {
        int ret;
        OM_uint32 maj_stat, min_stat;
index b963fbdca44d7817a0c57a3f16cfe69df983725e..aaa7d7f0da1c2d6ecd444e903f1cecdc93f66edc 100644 (file)
 #include <gssapi/gssapi.h>
 #include <krb5.h>
 
-struct ccache_container;
-
 struct gssapi_creds_container {
        gss_cred_id_t creds;
 };
 
+/* Manually prototyped here to avoid needing gss headers in most callers */
+int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, 
+                                        struct loadparm_context *lp_ctx,
+                                        gss_cred_id_t gssapi_cred,
+                                        enum credentials_obtained obtained);
+
+/* Manually prototyped here to avoid needing krb5 headers in most callers */
+krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 
+                                          struct cli_credentials *credentials, 
+                                          struct smb_krb5_context *smb_krb5_context,
+                                          krb5_principal *princ);
+       
 #endif /* __CREDENTIALS_KRB5_H__ */
index 70e2961d552daa5383fbbfc22dd6826af8adecae..e905e3e704a775981fd7e20a590fe04832e6297f 100644 (file)
@@ -101,10 +101,10 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
  * the library routines.  The returned princ is placed in the talloc
  * system by means of a destructor (do *not* free). */
 
-krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 
-                                          struct cli_credentials *credentials, 
-                                          struct smb_krb5_context *smb_krb5_context,
-                                          krb5_principal *princ)
+ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 
+                                           struct cli_credentials *credentials, 
+                                           struct smb_krb5_context *smb_krb5_context,
+                                           krb5_principal *princ)
 {
        krb5_error_code ret;
        const char *princ_string;
index 905cd4a995d5916a8d81e2eea32b487886e3f3a1..5407db99565c063806e03d4d9c6403d009581f71 100644 (file)
@@ -293,7 +293,7 @@ int samldb_notice_sid(struct ldb_module *module,
        /* find the domain DN */
        ret = ldb_search_exp_fmt(module->ldb, mem_ctx, &dom_res,
                                 NULL, LDB_SCOPE_SUBTREE, attrs,
-                                "(&(objectSid=%s)(objectclass=domain))",
+                                "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))", 
                                 ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
        if (ret == LDB_SUCCESS) {
                if (dom_res->count == 0) {
@@ -369,7 +369,7 @@ static int samldb_generate_samAccountName(struct ldb_module *module, TALLOC_CTX
        /* Format: $000000-000000000000 */
        
        do {
-               *name = talloc_asprintf(mem_ctx, "$%.6X-%.6X%.6X", (unsigned int)random(), (unsigned int)random(), (unsigned int)random());
+               *name = talloc_asprintf(mem_ctx, "$%.6X-%.6X%.6X", (unsigned int)generate_random(), (unsigned int)generate_random(), (unsigned int)generate_random());
                /* TODO: Figure out exactly what this is meant to conflict with */
                ret = ldb_search_exp_fmt(module->ldb,
                                         mem_ctx, &res, dom_dn, LDB_SCOPE_SUBTREE, attrs,
index 358ca5ad56d7162b2a083c38e127057b90035f87..b845b0f9a894e03760881a35d009e2647cdd95e5 100644 (file)
@@ -34,7 +34,7 @@
 #include "kdc_locl.h"
 #include <hex.h>
 
-RCSID("$Id: digest.c 21606 2007-07-17 07:03:25Z lha $");
+RCSID("$Id: digest.c 22374 2007-12-28 18:36:52Z lha $");
 
 #define MS_CHAP_V2     0x20
 #define CHAP_MD5       0x10
@@ -1003,7 +1003,8 @@ _kdc_do_digest(krb5_context context,
        }
 
        r.u.ntlmInitReply.flags |= 
-           NTLM_NEG_TARGET_DOMAIN |
+           NTLM_NEG_TARGET |
+           NTLM_TARGET_DOMAIN |
            NTLM_ENC_128;
 
 #define ALL                                    \
@@ -1331,6 +1332,27 @@ _kdc_do_digest(krb5_context context,
                version, ireq.u.ntlmRequest.username);
        break;
     }
+    case choice_DigestReqInner_supportedMechs:
+
+       kdc_log(context, config, 0, "digest supportedMechs from %s", from);
+
+       r.element = choice_DigestRepInner_supportedMechs;
+       memset(&r.u.supportedMechs, 0, sizeof(r.u.supportedMechs));
+
+       if (config->digests_allowed & NTLM_V1)
+           r.u.supportedMechs.ntlm_v1 = 1;
+       if (config->digests_allowed & NTLM_V1_SESSION)
+           r.u.supportedMechs.ntlm_v1_session = 1;
+       if (config->digests_allowed & NTLM_V2)
+           r.u.supportedMechs.ntlm_v2 = 1;
+       if (config->digests_allowed & DIGEST_MD5)
+           r.u.supportedMechs.digest_md5 = 1;
+       if (config->digests_allowed & CHAP_MD5)
+           r.u.supportedMechs.chap_md5 = 1;
+       if (config->digests_allowed & MS_CHAP_V2)
+           r.u.supportedMechs.ms_chap_v2 = 1;
+       break;
+
     default: {
        char *s;
        krb5_set_error_string(context, "unknown operation to digest");
index 15624e8e76393b03ccd97c6533bd5c30895fbd77..27f497ea6643c5ecc485160061b5e0840e28fbec 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kaserver.c 21661 2007-07-22 01:57:17Z lha $");
+RCSID("$Id: kaserver.c 21654 2007-07-21 17:30:18Z lha $");
 
 #include <krb5-v4compat.h>
 #include <rx.h>
index fdbdf271defa233a161caf75256e03828517a977..fe0523665a4dbf983b299ecfbbcdffb095becb4b 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 /* 
- * $Id: kdc_locl.h 20954 2007-06-07 03:30:15Z lha $ 
+ * $Id: kdc_locl.h 22247 2007-12-08 23:49:41Z lha $ 
  */
 
 #ifndef __KDC_LOCL_H__
@@ -58,8 +58,7 @@ extern int detach_from_console;
 
 extern const struct units _kdc_digestunits[];
 
-#define _PATH_KDC_CONF         HDB_DB_DIR "/kdc.conf"
-#define DEFAULT_LOG_DEST       "0-1/FILE:" HDB_DB_DIR "/kdc.log"
+#define KDC_LOG_FILE           "kdc.log"
 
 extern struct timeval _kdc_now;
 #define kdc_time (_kdc_now.tv_sec)
index 23ca5a035ec67365038e2e753c3a57885c55f2d4..f1dea6499df0252d71c15d4c64dcb27e7da02f65 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: kerberos5.c 21529 2007-07-13 12:37:14Z lha $");
+RCSID("$Id: kerberos5.c 22071 2007-11-14 20:04:50Z lha $");
 
 #define MAX_TIME ((time_t)((1U << 31) - 1))
 
@@ -362,6 +362,13 @@ older_enctype(krb5_enctype enctype)
     case ETYPE_DES3_CBC_SHA1:
     case ETYPE_ARCFOUR_HMAC_MD5:
     case ETYPE_ARCFOUR_HMAC_MD5_56:
+    /* 
+     * The following three is "old" windows enctypes and is needed for
+     * windows 2000 hosts.
+     */
+    case ETYPE_ARCFOUR_MD4:
+    case ETYPE_ARCFOUR_HMAC_OLD:
+    case ETYPE_ARCFOUR_HMAC_OLD_EXP:
        return 1;
     default:
        return 0;
@@ -411,8 +418,8 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
        *ent->salttype = key->salt->type;
 #else
        /* 
-        * We shouldn't sent salttype since its incompatible with the
-        * specification and its break windows clients.  The afs
+        * We shouldn't sent salttype since it is incompatible with the
+        * specification and it breaks windows clients.  The afs
         * salting problem is solved by using KRB5-PADATA-AFS3-SALT
         * implemented in Heimdal 0.7 and later.
         */
@@ -472,11 +479,13 @@ get_pa_etype_info(krb5_context context,
                    free_ETYPE_INFO(&pa);
                    return ret;
                }
+               break;
            }
        }
     skip1:;
     }
     for(i = 0; i < client->keys.len; i++) {
+       /* already added? */
        for(j = 0; j < etypes_len; j++) {
            if(client->keys.val[i].key.keytype == etypes[j])
                goto skip2;
@@ -497,7 +506,7 @@ get_pa_etype_info(krb5_context context,
     }
     
     if(n < pa.len) {
-       /* stripped out newer enctypes */
+       /* stripped out dups, newer enctypes, and not valid enctypes */
        pa.len = n;
     }
 
@@ -621,23 +630,29 @@ get_pa_etype_info2(krb5_context context,
            if(client->keys.val[i].key.keytype == etypes[j]) {
                if (krb5_enctype_valid(context, etypes[j]) != 0)
                    continue;
+               if (n >= pa.len)
+                   krb5_abortx(context, "internal error: n >= p.len");
                if((ret = make_etype_info2_entry(&pa.val[n++], 
                                                 &client->keys.val[i])) != 0) {
                    free_ETYPE_INFO2(&pa);
                    return ret;
                }
+               break;
            }
        }
     skip1:;
     }
-    /* send enctypes that the cliene doesn't know about too */
+    /* send enctypes that the client doesn't know about too */
     for(i = 0; i < client->keys.len; i++) {
+       /* already added? */
        for(j = 0; j < etypes_len; j++) {
            if(client->keys.val[i].key.keytype == etypes[j])
                goto skip2;
        }
        if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
            continue;
+       if (n >= pa.len)
+           krb5_abortx(context, "internal error: n >= p.len");
        if((ret = make_etype_info2_entry(&pa.val[n++],
                                         &client->keys.val[i])) != 0) {
            free_ETYPE_INFO2(&pa);
@@ -646,16 +661,8 @@ get_pa_etype_info2(krb5_context context,
       skip2:;
     }
     
-    if(n != pa.len) {
-       char *name;
-       ret = krb5_unparse_name(context, client->principal, &name);
-       if (ret)
-           name = rk_UNCONST("<unparse_name failed>");
-       kdc_log(context, config, 0,
-               "internal error in get_pa_etype_info2(%s): %d != %d", 
-               name, n, pa.len);
-       if (ret == 0)
-           free(name);
+    if(n < pa.len) {
+       /* stripped out dups, and not valid enctypes */
        pa.len = n;
     }
 
@@ -1554,6 +1561,10 @@ _kdc_as_rep(krb5_context context,
      * otherwise just a dummy lr.
      */
     ek.last_req.val = malloc(2 * sizeof(*ek.last_req.val));
+    if (ek.last_req.val == NULL) {
+       ret = ENOMEM;
+       goto out;
+    }
     ek.last_req.len = 0;
     if (client->entry.pw_end
        && (config->kdc_warn_pwexpire == 0
index 4d6be60f68fe2d40012604b2069a72dadaee161d..32bdee9799ca8407852b3ac2881465645839eaa2 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: krb5tgs.c 21262 2007-06-21 15:18:37Z lha $");
+RCSID("$Id: krb5tgs.c 22071 2007-11-14 20:04:50Z lha $");
 
 /*
  * return the realm of a krbtgt-ticket or NULL
@@ -822,7 +822,7 @@ tgs_make_reply(krb5_context context,
     if(rspac->length) {
        /*
         * No not need to filter out the any PAC from the
-        * auth_data since its signed by the KDC.
+        * auth_data since it's signed by the KDC.
         */
        ret = _kdc_tkt_add_if_relevant_ad(context, &et,
                                          KRB5_AUTHDATA_WIN2K_PAC,
@@ -1099,11 +1099,14 @@ tgs_parse_request(krb5_context context,
     ret = hdb_enctype2key(context, &(*krbtgt)->entry, 
                          ap_req.ticket.enc_part.etype, &tkey);
     if(ret){
-       char *str, *p;
+       char *str = NULL, *p = NULL;
+
        krb5_enctype_to_string(context, ap_req.ticket.enc_part.etype, &str);
        krb5_unparse_name(context, princ, &p);
-       kdc_log(context, config, 0,
-               "No server key with enctype %s found for %s", str, p);
+       kdc_log(context, config, 0,
+               "No server key with enctype %s found for %s",
+               str ? str : "<unknown enctype>",
+               p ? p : "<unparse_name failed>");
        free(str);
        free(p);
        ret = KRB5KRB_AP_ERR_BADKEYVER;
@@ -1163,8 +1166,10 @@ tgs_parse_request(krb5_context context,
     }
 
     if (b->enc_authorization_data) {
+       unsigned usage = KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY;
        krb5_keyblock *subkey;
        krb5_data ad;
+
        ret = krb5_auth_con_getremotesubkey(context,
                                            ac,
                                            &subkey);
@@ -1175,6 +1180,7 @@ tgs_parse_request(krb5_context context,
            goto out;
        }
        if(subkey == NULL){
+           usage = KRB5_KU_TGS_REQ_AUTH_DAT_SESSION;
            ret = krb5_auth_con_getkey(context, ac, &subkey);
            if(ret) {
                krb5_auth_con_free(context, ac);
@@ -1199,7 +1205,7 @@ tgs_parse_request(krb5_context context,
        }
        ret = krb5_decrypt_EncryptedData (context,
                                          crypto,
-                                         KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY,
+                                         usage,
                                          b->enc_authorization_data,
                                          &ad);
        krb5_crypto_destroy(context, crypto);
@@ -1373,6 +1379,7 @@ server_lookup:
                    ret = krb5_unparse_name(context, sp, &spn); 
                    if (ret)
                        goto out;
+                   auth_data = NULL; /* ms don't handle AD in referals */
                    goto server_lookup;
                }
            }
@@ -1390,6 +1397,7 @@ server_lookup:
                if (ret)
                    goto out;
                krb5_free_host_realm(context, realms);
+               auth_data = NULL; /* ms don't handle AD in referals */
                goto server_lookup;
            }
            krb5_free_host_realm(context, realms);
@@ -1431,8 +1439,8 @@ server_lookup:
     }
     
     /*
-     * Check that service is in the same realm as the krbtgt. If its
-     * not the same, its someone that is using a uni-directional trust
+     * Check that service is in the same realm as the krbtgt. If it's
+     * not the same, it's someone that is using a uni-directional trust
      * backward.
      */
     
index 977b1c9476015f3bd41a557cf57b74ef546eebc7..8cf967fbfb8b179da9055e96c8e9df0e2c359bc4 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "kdc_locl.h"
-RCSID("$Id: log.c 15532 2005-06-30 01:54:49Z lha $");
+RCSID("$Id: log.c 22254 2007-12-09 06:01:05Z lha $");
 
 void
 kdc_openlog(krb5_context context, 
@@ -47,8 +47,12 @@ kdc_openlog(krb5_context context,
        for(p = s; *p; p++)
            krb5_addlog_dest(context, config->logf, *p);
        krb5_config_free_strings(s);
-    }else
-       krb5_addlog_dest(context, config->logf, DEFAULT_LOG_DEST);
+    }else {
+       char *s;
+       asprintf(&s, "0-1/FILE:%s/%s", hdb_db_dir(context), KDC_LOG_FILE);
+       krb5_addlog_dest(context, config->logf, s);
+       free(s);
+    }
     krb5_set_warn_dest(context, config->logf);
 }
 
index ead961022d18a27fc9f3c177d03157112ab0a7d6..bf248af588fcbbb81d6ae7abfeabfcec81c551cc 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: pkinit.c 21290 2007-06-25 14:13:23Z lha $");
+RCSID("$Id: pkinit.c 22243 2007-12-08 23:39:30Z lha $");
 
 #ifdef PKINIT
 
@@ -1248,6 +1248,7 @@ out:
 static int
 match_rfc_san(krb5_context context, 
              krb5_kdc_configuration *config,
+             hx509_context hx509ctx,
              hx509_cert client_cert, 
              krb5_const_principal match)
 {
@@ -1256,7 +1257,8 @@ match_rfc_san(krb5_context context,
 
     memset(&list, 0 , sizeof(list));
 
-    ret = hx509_cert_find_subjectAltName_otherName(client_cert,
+    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
+                                                  client_cert,
                                                   oid_id_pkinit_san(),
                                                   &list);
     if (ret)
@@ -1304,6 +1306,7 @@ out:
 static int
 match_ms_upn_san(krb5_context context, 
                 krb5_kdc_configuration *config,
+                hx509_context hx509ctx,
                 hx509_cert client_cert, 
                 krb5_const_principal match)
 {
@@ -1315,7 +1318,8 @@ match_ms_upn_san(krb5_context context,
 
     memset(&list, 0 , sizeof(list));
 
-    ret = hx509_cert_find_subjectAltName_otherName(client_cert,
+    ret = hx509_cert_find_subjectAltName_otherName(hx509ctx,
+                                                  client_cert,
                                                   oid_id_pkinit_ms_san(),
                                                   &list);
     if (ret)
@@ -1376,7 +1380,7 @@ _kdc_pk_check_client(krb5_context context,
     hx509_name name;
     int i;
 
-    ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx, 
+    ret = hx509_cert_get_base_subject(kdc_identity->hx509ctx,
                                      client_params->cert,
                                      &name);
     if (ret)
@@ -1393,6 +1397,7 @@ _kdc_pk_check_client(krb5_context context,
 
     if (config->pkinit_princ_in_cert) {
        ret = match_rfc_san(context, config,
+                           kdc_identity->hx509ctx,
                            client_params->cert,
                            client->entry.principal);
        if (ret == 0) {
@@ -1401,6 +1406,7 @@ _kdc_pk_check_client(krb5_context context,
            return 0;
        }
        ret = match_ms_upn_san(context, config,
+                              kdc_identity->hx509ctx,
                               client_params->cert,
                               client->entry.principal);
        if (ret == 0) {
@@ -1580,7 +1586,8 @@ _kdc_pk_initialize(krb5_context context,
                   char **pool,
                   char **revoke_list)
 {
-    const char *file; 
+    const char *file;
+    char *fn = NULL;
     krb5_error_code ret;
 
     file = krb5_config_get_string(context, NULL,
@@ -1646,14 +1653,19 @@ _kdc_pk_initialize(krb5_context context,
                                       NULL);
     _krb5_pk_allow_proxy_certificate(kdc_identity, ret);
 
-    file = krb5_config_get_string_default(context, 
-                                         NULL,
-                                         HDB_DB_DIR "/pki-mapping",
-                                         "kdc",
-                                         "pkinit_mappings_file",
-                                         NULL);
+    file = krb5_config_get_string(context, 
+                                 NULL,
+                                 "kdc",
+                                 "pkinit_mappings_file",
+                                 NULL);
+    if (file == NULL) {
+       asprintf(&fn, "%s/pki-mapping", hdb_db_dir(context));
+       file = fn;
+    }
 
     load_mappings(context, file);
+    if (fn)
+       free(fn);
 
     return 0;
 }
index 23fa7a5bafb0623cb2188811cca4bbf53a230ce9..2676309859089bda9136eeaa0d157e9c48cad707 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -32,7 +32,7 @@
  */
 
 #include "kuser_locl.h"
-RCSID("$Id: kinit.c 21483 2007-07-10 16:40:46Z lha $");
+RCSID("$Id: kinit.c 22116 2007-12-03 21:22:58Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -260,7 +260,7 @@ renew_validate(krb5_context context,
 
     if (renew) {
        /* 
-        * no need to check the error here, its only to be 
+        * no need to check the error here, it's only to be 
         * friendly to the user
         */
        krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out);
@@ -377,6 +377,7 @@ get_new_tickets(krb5_context context,
     char *renewstr = NULL;
     krb5_enctype *enctype = NULL;
     struct ntlm_buf ntlmkey;
+    krb5_ccache tempccache;
 
     memset(&ntlmkey, 0, sizeof(ntlmkey));
     passwd[0] = '\0';
@@ -577,16 +578,25 @@ get_new_tickets(krb5_context context,
        }
     }
 
-    ret = krb5_cc_initialize (context, ccache, cred.client);
+    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache), 
+                            NULL, &tempccache);
+    if (ret)
+       krb5_err (context, 1, ret, "krb5_cc_new_unique");
+
+    ret = krb5_cc_initialize (context, tempccache, cred.client);
     if (ret)
        krb5_err (context, 1, ret, "krb5_cc_initialize");
     
-    ret = krb5_cc_store_cred (context, ccache, &cred);
+    ret = krb5_cc_store_cred (context, tempccache, &cred);
     if (ret)
        krb5_err (context, 1, ret, "krb5_cc_store_cred");
 
     krb5_free_cred_contents (context, &cred);
 
+    ret = krb5_cc_move(context, tempccache, ccache);
+    if (ret)
+       krb5_err (context, 1, ret, "krb5_cc_move");
+
     if (ntlm_domain && ntlmkey.data)
        store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey);
 
@@ -757,8 +767,11 @@ main (int argc, char **argv)
                    krb4_cc_name = NULL;
                }
            }
-       } else
-           ret = krb5_cc_default (context, &ccache);
+       } else {
+           ret = krb5_cc_cache_match(context, principal, NULL, &ccache);
+           if (ret)
+               ret = krb5_cc_default (context, &ccache);
+       }
     }
     if (ret)
        krb5_err (context, 1, ret, "resolving credentials cache");
index 15c4a09cd0d0725492c3ab9f155508a363dfe1ab..5789e0f22dfbb03c3a4bb7c83ae5690dda7acdb7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: asn1-common.h 19539 2006-12-28 17:15:05Z lha $ */
+/* $Id: asn1-common.h 22429 2008-01-13 10:25:50Z lha $ */
 
 #include <stddef.h>
 #include <time.h>
index edb8375ee35c38b20d967ad87c0096976250639c..5ba3e3880c2e23a5fae1aa90140073ce5e3fd370 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: canthandle.asn1 16593 2006-01-18 19:12:33Z lha $ --
+-- $Id: canthandle.asn1 22071 2007-11-14 20:04:50Z lha $ --
 
 CANTHANDLE DEFINITIONS ::= BEGIN
 
@@ -19,7 +19,7 @@ Foo ::= SEQUENCE {
         kaka3 [2] IMPLICIT Kaka3 OPTIONAL
 }
 
--- Don't code kaka if its 1
+-- Don't code kaka if it's 1
 -- Workaround is to use OPTIONAL and check for in the encoder stubs
 
 Bar ::= SEQUENCE {
index c7b911b8d6c82cc8601c187c0df32436d20bf804..120dc086afc9383c9e19b4386120bbc2c9492148 100644 (file)
@@ -38,7 +38,7 @@
 #include <getarg.h>
 #include <err.h>
 
-RCSID("$Id: der.c 15617 2005-07-12 06:27:42Z lha $");
+RCSID("$Id: der.c 22429 2008-01-13 10:25:50Z lha $");
 
 
 static const char *class_names[] = {
index 17341863c66b080ad49301dd73d939733604fd3e..eafe48ea5aee1e57bfa361863494e6f976429fe9 100644 (file)
@@ -1,10 +1,19 @@
--- $Id: digest.asn1 20138 2007-02-02 21:08:24Z lha $
+-- $Id: digest.asn1 22152 2007-12-04 19:59:18Z lha $
 
 DIGEST DEFINITIONS ::=
 BEGIN
 
 IMPORTS EncryptedData, Principal FROM krb5;
 
+DigestTypes ::= BIT STRING {
+       ntlm-v1(0),
+       ntlm-v1-session(1),
+       ntlm-v2(2),
+       digest-md5(3),
+       chap-md5(4),
+       ms-chap-v2(5)
+}
+
 DigestInit ::= SEQUENCE {
     type               UTF8String, -- http, sasl, chap, cram-md5 --
     channel            [0] SEQUENCE {
@@ -95,7 +104,8 @@ DigestReqInner ::= CHOICE {
     init               [0] DigestInit,
     digestRequest      [1] DigestRequest,
     ntlmInit           [2] NTLMInit,
-    ntlmRequest                [3] NTLMRequest
+    ntlmRequest                [3] NTLMRequest,
+    supportedMechs     [4] NULL
 }
 
 DigestREQ ::= [APPLICATION 128] SEQUENCE {
@@ -108,7 +118,9 @@ DigestRepInner ::= CHOICE {
     initReply          [1] DigestInitReply,
     response           [2] DigestResponse,
     ntlmInitReply      [3] NTLMInitReply,
-    ntlmResponse       [4] NTLMResponse
+    ntlmResponse       [4] NTLMResponse,
+    supportedMechs     [5] DigestTypes,
+    ...
 }
 
 DigestREP ::= [APPLICATION 129] SEQUENCE {
index 26890212ae6425c6249381f3d3ebfe424e686943..499f8eab363b56f51392a5f0977c3a894b90b795 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen.c 21364 2007-06-27 08:51:06Z lha $");
+RCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $");
 
 FILE *headerfile, *codefile, *logfile;
 
index 9544514212f89f543db40b6e2f0386231d4d86fc..08f1a9449f8baf91dda4105df2bdcccdc9d77bb1 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_encode.c 21503 2007-07-12 11:57:19Z lha $");
+RCSID("$Id: gen_encode.c 22429 2008-01-13 10:25:50Z lha $");
 
 static void
 encode_primitive (const char *typename, const char *name)
index e3fe2b11e9ac297a631c21e11a507c64bccdd30e..18f1e1541b5f6723b256ac89645abab219cc52a3 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: k5.asn1 21400 2007-07-02 19:57:31Z lha $
+-- $Id: k5.asn1 21965 2007-10-18 18:24:36Z lha $
 
 KERBEROS5 DEFINITIONS ::=
 BEGIN
@@ -137,6 +137,10 @@ ENCTYPE ::= INTEGER {
        ETYPE_ARCFOUR_HMAC_MD5(23),
        ETYPE_ARCFOUR_HMAC_MD5_56(24),
        ETYPE_ENCTYPE_PK_CROSS(48),
+-- some "old" windows types
+       ETYPE_ARCFOUR_MD4(-128),
+       ETYPE_ARCFOUR_HMAC_OLD(-133),
+       ETYPE_ARCFOUR_HMAC_OLD_EXP(-135),
 -- these are for Heimdal internal use
        ETYPE_DES_CBC_NONE(-0x1000),
        ETYPE_DES3_CBC_NONE(-0x1001),
index 86c4359f1a0f9a537f58a4f1a9bab2045c1f8b71..da4f729c3d6966e6026ada705541fea8c93ac16a 100644 (file)
@@ -1,6 +1,5 @@
-#include "config.h"
 
-#line 3 "heimdal/lib/asn1/lex.c"
+#line 3 "lex.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -827,7 +826,7 @@ char *yytext;
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.l,v 1.31 2006/10/21 11:57:22 lha Exp $ */
+/* $Id: lex.l 18738 2006-10-21 11:57:22Z lha $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -852,7 +851,7 @@ static unsigned lineno = 1;
 static void unterminated(const char *, unsigned);
 
 /* This is for broken old lexes (solaris 10 and hpux) */
-#line 855 "heimdal/lib/asn1/lex.c"
+#line 855 "lex.c"
 
 #define INITIAL 0
 
@@ -870,6 +869,35 @@ static void unterminated(const char *, unsigned);
 
 static int yy_init_globals (void );
 
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * out_str  );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number  );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -1007,7 +1035,7 @@ YY_DECL
     
 #line 68 "lex.l"
 
-#line 1010 "heimdal/lib/asn1/lex.c"
+#line 1039 "lex.c"
 
        if ( !(yy_init) )
                {
@@ -1676,7 +1704,7 @@ YY_RULE_SETUP
 #line 274 "lex.l"
 ECHO;
        YY_BREAK
-#line 1679 "heimdal/lib/asn1/lex.c"
+#line 1708 "lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -1907,7 +1935,7 @@ static int yy_get_next_buffer (void)
 
                /* Read in more data. */
                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), (size_t) num_to_read );
+                       (yy_n_chars), num_to_read );
 
                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
                }
@@ -2408,7 +2436,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 
 /** Setup the input buffer state to scan a string. The next call to yylex() will
  * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
index edcb313bd02bffbfb07e60ecd376a9bd3fc2b06e..6a3e524e93a949e354eb856ee69029c2eebb1ef9 100644 (file)
 
 
 /* Copy the first part of user declarations.  */
-#line 36 "heimdal/lib/asn1/parse.y"
+#line 36 "parse.y"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -280,7 +280,7 @@ struct string_list {
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG 0
+# define YYDEBUG 1
 #endif
 
 /* Enabling verbose error messages.  */
@@ -298,7 +298,7 @@ struct string_list {
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 65 "heimdal/lib/asn1/parse.y"
+#line 65 "parse.y"
 {
     int constant;
     struct value *value;
@@ -314,7 +314,7 @@ typedef union YYSTYPE
     struct constraint_spec *constraint_spec;
 }
 /* Line 187 of yacc.c.  */
-#line 318 "heimdal/lib/asn1/parse.y"
+#line 318 "parse.c"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -327,7 +327,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 331 "heimdal/lib/asn1/parse.y"
+#line 331 "parse.c"
 
 #ifdef short
 # undef short
@@ -1762,29 +1762,29 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 235 "heimdal/lib/asn1/parse.y"
+#line 235 "parse.y"
     {
                        checkundefined();
                }
     break;
 
   case 4:
-#line 242 "heimdal/lib/asn1/parse.y"
+#line 242 "parse.y"
     { error_message("implicit tagging is not supported"); }
     break;
 
   case 5:
-#line 244 "heimdal/lib/asn1/parse.y"
+#line 244 "parse.y"
     { error_message("automatic tagging is not supported"); }
     break;
 
   case 7:
-#line 249 "heimdal/lib/asn1/parse.y"
+#line 249 "parse.y"
     { error_message("no extensibility options supported"); }
     break;
 
   case 17:
-#line 270 "heimdal/lib/asn1/parse.y"
+#line 270 "parse.y"
     { 
                    struct string_list *sl;
                    for(sl = (yyvsp[(1) - (4)].sl); sl != NULL; sl = sl->next) {
@@ -1796,7 +1796,7 @@ yyreduce:
     break;
 
   case 22:
-#line 289 "heimdal/lib/asn1/parse.y"
+#line 289 "parse.y"
     {
                    (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
                    (yyval.sl)->string = (yyvsp[(1) - (3)].name);
@@ -1805,7 +1805,7 @@ yyreduce:
     break;
 
   case 23:
-#line 295 "heimdal/lib/asn1/parse.y"
+#line 295 "parse.y"
     {
                    (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
                    (yyval.sl)->string = (yyvsp[(1) - (1)].name);
@@ -1814,7 +1814,7 @@ yyreduce:
     break;
 
   case 24:
-#line 303 "heimdal/lib/asn1/parse.y"
+#line 303 "parse.y"
     {
                    Symbol *s = addsym ((yyvsp[(1) - (3)].name));
                    s->stype = Stype;
@@ -1825,7 +1825,7 @@ yyreduce:
     break;
 
   case 42:
-#line 334 "heimdal/lib/asn1/parse.y"
+#line 334 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_Boolean, 
                                     TE_EXPLICIT, new_type(TBoolean));
@@ -1833,7 +1833,7 @@ yyreduce:
     break;
 
   case 43:
-#line 341 "heimdal/lib/asn1/parse.y"
+#line 341 "parse.y"
     {
                    if((yyvsp[(2) - (5)].value)->type != integervalue)
                        error_message("Non-integer used in first part of range");
@@ -1846,7 +1846,7 @@ yyreduce:
     break;
 
   case 44:
-#line 351 "heimdal/lib/asn1/parse.y"
+#line 351 "parse.y"
     {          
                    if((yyvsp[(2) - (5)].value)->type != integervalue)
                        error_message("Non-integer in first part of range");
@@ -1857,7 +1857,7 @@ yyreduce:
     break;
 
   case 45:
-#line 359 "heimdal/lib/asn1/parse.y"
+#line 359 "parse.y"
     {          
                    if((yyvsp[(4) - (5)].value)->type != integervalue)
                        error_message("Non-integer in second part of range");
@@ -1868,7 +1868,7 @@ yyreduce:
     break;
 
   case 46:
-#line 367 "heimdal/lib/asn1/parse.y"
+#line 367 "parse.y"
     {
                    if((yyvsp[(2) - (3)].value)->type != integervalue)
                        error_message("Non-integer used in limit");
@@ -1879,7 +1879,7 @@ yyreduce:
     break;
 
   case 47:
-#line 378 "heimdal/lib/asn1/parse.y"
+#line 378 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, 
                                     TE_EXPLICIT, new_type(TInteger));
@@ -1887,7 +1887,7 @@ yyreduce:
     break;
 
   case 48:
-#line 383 "heimdal/lib/asn1/parse.y"
+#line 383 "parse.y"
     {
                        (yyval.type) = new_type(TInteger);
                        (yyval.type)->range = (yyvsp[(2) - (2)].range);
@@ -1896,7 +1896,7 @@ yyreduce:
     break;
 
   case 49:
-#line 389 "heimdal/lib/asn1/parse.y"
+#line 389 "parse.y"
     {
                  (yyval.type) = new_type(TInteger);
                  (yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -1905,7 +1905,7 @@ yyreduce:
     break;
 
   case 50:
-#line 397 "heimdal/lib/asn1/parse.y"
+#line 397 "parse.y"
     {
                        (yyval.members) = emalloc(sizeof(*(yyval.members)));
                        ASN1_TAILQ_INIT((yyval.members));
@@ -1914,7 +1914,7 @@ yyreduce:
     break;
 
   case 51:
-#line 403 "heimdal/lib/asn1/parse.y"
+#line 403 "parse.y"
     {
                        ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
                        (yyval.members) = (yyvsp[(1) - (3)].members);
@@ -1922,12 +1922,12 @@ yyreduce:
     break;
 
   case 52:
-#line 408 "heimdal/lib/asn1/parse.y"
+#line 408 "parse.y"
     { (yyval.members) = (yyvsp[(1) - (3)].members); }
     break;
 
   case 53:
-#line 412 "heimdal/lib/asn1/parse.y"
+#line 412 "parse.y"
     {
                        (yyval.member) = emalloc(sizeof(*(yyval.member)));
                        (yyval.member)->name = (yyvsp[(1) - (4)].name);
@@ -1941,7 +1941,7 @@ yyreduce:
     break;
 
   case 54:
-#line 425 "heimdal/lib/asn1/parse.y"
+#line 425 "parse.y"
     {
                  (yyval.type) = new_type(TInteger);
                  (yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -1950,7 +1950,7 @@ yyreduce:
     break;
 
   case 56:
-#line 436 "heimdal/lib/asn1/parse.y"
+#line 436 "parse.y"
     {
                  (yyval.type) = new_type(TBitString);
                  (yyval.type)->members = emalloc(sizeof(*(yyval.type)->members));
@@ -1960,7 +1960,7 @@ yyreduce:
     break;
 
   case 57:
-#line 443 "heimdal/lib/asn1/parse.y"
+#line 443 "parse.y"
     {
                  (yyval.type) = new_type(TBitString);
                  (yyval.type)->members = (yyvsp[(4) - (5)].members);
@@ -1969,7 +1969,7 @@ yyreduce:
     break;
 
   case 58:
-#line 451 "heimdal/lib/asn1/parse.y"
+#line 451 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_OID, 
                                     TE_EXPLICIT, new_type(TOID));
@@ -1977,7 +1977,7 @@ yyreduce:
     break;
 
   case 59:
-#line 457 "heimdal/lib/asn1/parse.y"
+#line 457 "parse.y"
     {
                    Type *t = new_type(TOctetString);
                    t->range = (yyvsp[(3) - (3)].range);
@@ -1987,7 +1987,7 @@ yyreduce:
     break;
 
   case 60:
-#line 466 "heimdal/lib/asn1/parse.y"
+#line 466 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_Null, 
                                     TE_EXPLICIT, new_type(TNull));
@@ -1995,17 +1995,17 @@ yyreduce:
     break;
 
   case 61:
-#line 473 "heimdal/lib/asn1/parse.y"
+#line 473 "parse.y"
     { (yyval.range) = NULL; }
     break;
 
   case 62:
-#line 475 "heimdal/lib/asn1/parse.y"
+#line 475 "parse.y"
     { (yyval.range) = (yyvsp[(2) - (2)].range); }
     break;
 
   case 63:
-#line 480 "heimdal/lib/asn1/parse.y"
+#line 480 "parse.y"
     {
                  (yyval.type) = new_type(TSequence);
                  (yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2014,7 +2014,7 @@ yyreduce:
     break;
 
   case 64:
-#line 486 "heimdal/lib/asn1/parse.y"
+#line 486 "parse.y"
     {
                  (yyval.type) = new_type(TSequence);
                  (yyval.type)->members = NULL;
@@ -2023,7 +2023,7 @@ yyreduce:
     break;
 
   case 65:
-#line 494 "heimdal/lib/asn1/parse.y"
+#line 494 "parse.y"
     {
                  (yyval.type) = new_type(TSequenceOf);
                  (yyval.type)->range = (yyvsp[(2) - (4)].range);
@@ -2033,7 +2033,7 @@ yyreduce:
     break;
 
   case 66:
-#line 503 "heimdal/lib/asn1/parse.y"
+#line 503 "parse.y"
     {
                  (yyval.type) = new_type(TSet);
                  (yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2042,7 +2042,7 @@ yyreduce:
     break;
 
   case 67:
-#line 509 "heimdal/lib/asn1/parse.y"
+#line 509 "parse.y"
     {
                  (yyval.type) = new_type(TSet);
                  (yyval.type)->members = NULL;
@@ -2051,7 +2051,7 @@ yyreduce:
     break;
 
   case 68:
-#line 517 "heimdal/lib/asn1/parse.y"
+#line 517 "parse.y"
     {
                  (yyval.type) = new_type(TSetOf);
                  (yyval.type)->subtype = (yyvsp[(3) - (3)].type);
@@ -2060,7 +2060,7 @@ yyreduce:
     break;
 
   case 69:
-#line 525 "heimdal/lib/asn1/parse.y"
+#line 525 "parse.y"
     {
                  (yyval.type) = new_type(TChoice);
                  (yyval.type)->members = (yyvsp[(3) - (4)].members);
@@ -2068,7 +2068,7 @@ yyreduce:
     break;
 
   case 72:
-#line 536 "heimdal/lib/asn1/parse.y"
+#line 536 "parse.y"
     {
                  Symbol *s = addsym((yyvsp[(1) - (1)].name));
                  (yyval.type) = new_type(TType);
@@ -2080,7 +2080,7 @@ yyreduce:
     break;
 
   case 73:
-#line 547 "heimdal/lib/asn1/parse.y"
+#line 547 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
                                     TE_EXPLICIT, new_type(TGeneralizedTime));
@@ -2088,7 +2088,7 @@ yyreduce:
     break;
 
   case 74:
-#line 552 "heimdal/lib/asn1/parse.y"
+#line 552 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTCTime, 
                                     TE_EXPLICIT, new_type(TUTCTime));
@@ -2096,7 +2096,7 @@ yyreduce:
     break;
 
   case 75:
-#line 559 "heimdal/lib/asn1/parse.y"
+#line 559 "parse.y"
     {
                    /* if (Constraint.type == contentConstrant) {
                       assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
@@ -2112,14 +2112,14 @@ yyreduce:
     break;
 
   case 76:
-#line 575 "heimdal/lib/asn1/parse.y"
+#line 575 "parse.y"
     {
                    (yyval.constraint_spec) = (yyvsp[(2) - (3)].constraint_spec);
                }
     break;
 
   case 80:
-#line 588 "heimdal/lib/asn1/parse.y"
+#line 588 "parse.y"
     {
                    (yyval.constraint_spec) = new_constraint_spec(CT_CONTENTS);
                    (yyval.constraint_spec)->u.content.type = (yyvsp[(2) - (2)].type);
@@ -2128,7 +2128,7 @@ yyreduce:
     break;
 
   case 81:
-#line 594 "heimdal/lib/asn1/parse.y"
+#line 594 "parse.y"
     {
                    if ((yyvsp[(3) - (3)].value)->type != objectidentifiervalue)
                        error_message("Non-OID used in ENCODED BY constraint");
@@ -2139,7 +2139,7 @@ yyreduce:
     break;
 
   case 82:
-#line 602 "heimdal/lib/asn1/parse.y"
+#line 602 "parse.y"
     {
                    if ((yyvsp[(5) - (5)].value)->type != objectidentifiervalue)
                        error_message("Non-OID used in ENCODED BY constraint");
@@ -2150,14 +2150,14 @@ yyreduce:
     break;
 
   case 83:
-#line 612 "heimdal/lib/asn1/parse.y"
+#line 612 "parse.y"
     {
                    (yyval.constraint_spec) = new_constraint_spec(CT_USER);
                }
     break;
 
   case 84:
-#line 618 "heimdal/lib/asn1/parse.y"
+#line 618 "parse.y"
     {
                        (yyval.type) = new_type(TTag);
                        (yyval.type)->tag = (yyvsp[(1) - (3)].tag);
@@ -2171,7 +2171,7 @@ yyreduce:
     break;
 
   case 85:
-#line 631 "heimdal/lib/asn1/parse.y"
+#line 631 "parse.y"
     {
                        (yyval.tag).tagclass = (yyvsp[(2) - (4)].constant);
                        (yyval.tag).tagvalue = (yyvsp[(3) - (4)].constant);
@@ -2180,56 +2180,56 @@ yyreduce:
     break;
 
   case 86:
-#line 639 "heimdal/lib/asn1/parse.y"
+#line 639 "parse.y"
     {
                        (yyval.constant) = ASN1_C_CONTEXT;
                }
     break;
 
   case 87:
-#line 643 "heimdal/lib/asn1/parse.y"
+#line 643 "parse.y"
     {
                        (yyval.constant) = ASN1_C_UNIV;
                }
     break;
 
   case 88:
-#line 647 "heimdal/lib/asn1/parse.y"
+#line 647 "parse.y"
     {
                        (yyval.constant) = ASN1_C_APPL;
                }
     break;
 
   case 89:
-#line 651 "heimdal/lib/asn1/parse.y"
+#line 651 "parse.y"
     {
                        (yyval.constant) = ASN1_C_PRIVATE;
                }
     break;
 
   case 90:
-#line 657 "heimdal/lib/asn1/parse.y"
+#line 657 "parse.y"
     {
                        (yyval.constant) = TE_EXPLICIT;
                }
     break;
 
   case 91:
-#line 661 "heimdal/lib/asn1/parse.y"
+#line 661 "parse.y"
     {
                        (yyval.constant) = TE_EXPLICIT;
                }
     break;
 
   case 92:
-#line 665 "heimdal/lib/asn1/parse.y"
+#line 665 "parse.y"
     {
                        (yyval.constant) = TE_IMPLICIT;
                }
     break;
 
   case 93:
-#line 672 "heimdal/lib/asn1/parse.y"
+#line 672 "parse.y"
     {
                        Symbol *s;
                        s = addsym ((yyvsp[(1) - (4)].name));
@@ -2241,7 +2241,7 @@ yyreduce:
     break;
 
   case 95:
-#line 686 "heimdal/lib/asn1/parse.y"
+#line 686 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralString, 
                                     TE_EXPLICIT, new_type(TGeneralString));
@@ -2249,7 +2249,7 @@ yyreduce:
     break;
 
   case 96:
-#line 691 "heimdal/lib/asn1/parse.y"
+#line 691 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTF8String, 
                                     TE_EXPLICIT, new_type(TUTF8String));
@@ -2257,7 +2257,7 @@ yyreduce:
     break;
 
   case 97:
-#line 696 "heimdal/lib/asn1/parse.y"
+#line 696 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_PrintableString, 
                                     TE_EXPLICIT, new_type(TPrintableString));
@@ -2265,7 +2265,7 @@ yyreduce:
     break;
 
   case 98:
-#line 701 "heimdal/lib/asn1/parse.y"
+#line 701 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_VisibleString, 
                                     TE_EXPLICIT, new_type(TVisibleString));
@@ -2273,7 +2273,7 @@ yyreduce:
     break;
 
   case 99:
-#line 706 "heimdal/lib/asn1/parse.y"
+#line 706 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_IA5String, 
                                     TE_EXPLICIT, new_type(TIA5String));
@@ -2281,7 +2281,7 @@ yyreduce:
     break;
 
   case 100:
-#line 711 "heimdal/lib/asn1/parse.y"
+#line 711 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_BMPString, 
                                     TE_EXPLICIT, new_type(TBMPString));
@@ -2289,7 +2289,7 @@ yyreduce:
     break;
 
   case 101:
-#line 716 "heimdal/lib/asn1/parse.y"
+#line 716 "parse.y"
     {
                        (yyval.type) = new_tag(ASN1_C_UNIV, UT_UniversalString, 
                                     TE_EXPLICIT, new_type(TUniversalString));
@@ -2297,7 +2297,7 @@ yyreduce:
     break;
 
   case 102:
-#line 724 "heimdal/lib/asn1/parse.y"
+#line 724 "parse.y"
     {
                        (yyval.members) = emalloc(sizeof(*(yyval.members)));
                        ASN1_TAILQ_INIT((yyval.members));
@@ -2306,7 +2306,7 @@ yyreduce:
     break;
 
   case 103:
-#line 730 "heimdal/lib/asn1/parse.y"
+#line 730 "parse.y"
     {
                        ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
                        (yyval.members) = (yyvsp[(1) - (3)].members);
@@ -2314,7 +2314,7 @@ yyreduce:
     break;
 
   case 104:
-#line 735 "heimdal/lib/asn1/parse.y"
+#line 735 "parse.y"
     {
                        struct member *m = ecalloc(1, sizeof(*m));
                        m->name = estrdup("...");
@@ -2326,7 +2326,7 @@ yyreduce:
     break;
 
   case 105:
-#line 746 "heimdal/lib/asn1/parse.y"
+#line 746 "parse.y"
     {
                  (yyval.member) = emalloc(sizeof(*(yyval.member)));
                  (yyval.member)->name = (yyvsp[(1) - (2)].name);
@@ -2338,7 +2338,7 @@ yyreduce:
     break;
 
   case 106:
-#line 757 "heimdal/lib/asn1/parse.y"
+#line 757 "parse.y"
     {
                        (yyval.member) = (yyvsp[(1) - (1)].member);
                        (yyval.member)->optional = 0;
@@ -2347,7 +2347,7 @@ yyreduce:
     break;
 
   case 107:
-#line 763 "heimdal/lib/asn1/parse.y"
+#line 763 "parse.y"
     {
                        (yyval.member) = (yyvsp[(1) - (2)].member);
                        (yyval.member)->optional = 1;
@@ -2356,7 +2356,7 @@ yyreduce:
     break;
 
   case 108:
-#line 769 "heimdal/lib/asn1/parse.y"
+#line 769 "parse.y"
     {
                        (yyval.member) = (yyvsp[(1) - (3)].member);
                        (yyval.member)->optional = 0;
@@ -2365,7 +2365,7 @@ yyreduce:
     break;
 
   case 109:
-#line 777 "heimdal/lib/asn1/parse.y"
+#line 777 "parse.y"
     {
                        (yyval.members) = emalloc(sizeof(*(yyval.members)));
                        ASN1_TAILQ_INIT((yyval.members));
@@ -2374,7 +2374,7 @@ yyreduce:
     break;
 
   case 110:
-#line 783 "heimdal/lib/asn1/parse.y"
+#line 783 "parse.y"
     {
                        ASN1_TAILQ_INSERT_TAIL((yyvsp[(1) - (3)].members), (yyvsp[(3) - (3)].member), members);
                        (yyval.members) = (yyvsp[(1) - (3)].members);
@@ -2382,7 +2382,7 @@ yyreduce:
     break;
 
   case 111:
-#line 790 "heimdal/lib/asn1/parse.y"
+#line 790 "parse.y"
     {
                  (yyval.member) = emalloc(sizeof(*(yyval.member)));
                  (yyval.member)->name = (yyvsp[(1) - (4)].name);
@@ -2396,26 +2396,26 @@ yyreduce:
     break;
 
   case 113:
-#line 803 "heimdal/lib/asn1/parse.y"
+#line 803 "parse.y"
     { (yyval.objid) = NULL; }
     break;
 
   case 114:
-#line 807 "heimdal/lib/asn1/parse.y"
+#line 807 "parse.y"
     {
                        (yyval.objid) = (yyvsp[(2) - (3)].objid);
                }
     break;
 
   case 115:
-#line 813 "heimdal/lib/asn1/parse.y"
+#line 813 "parse.y"
     {
                        (yyval.objid) = NULL;
                }
     break;
 
   case 116:
-#line 817 "heimdal/lib/asn1/parse.y"
+#line 817 "parse.y"
     {
                        if ((yyvsp[(2) - (2)].objid)) {
                                (yyval.objid) = (yyvsp[(2) - (2)].objid);
@@ -2427,14 +2427,14 @@ yyreduce:
     break;
 
   case 117:
-#line 828 "heimdal/lib/asn1/parse.y"
+#line 828 "parse.y"
     {
                        (yyval.objid) = new_objid((yyvsp[(1) - (4)].name), (yyvsp[(3) - (4)].constant));
                }
     break;
 
   case 118:
-#line 832 "heimdal/lib/asn1/parse.y"
+#line 832 "parse.y"
     {
                    Symbol *s = addsym((yyvsp[(1) - (1)].name));
                    if(s->stype != SValue ||
@@ -2448,14 +2448,14 @@ yyreduce:
     break;
 
   case 119:
-#line 843 "heimdal/lib/asn1/parse.y"
+#line 843 "parse.y"
     {
                    (yyval.objid) = new_objid(NULL, (yyvsp[(1) - (1)].constant));
                }
     break;
 
   case 129:
-#line 866 "heimdal/lib/asn1/parse.y"
+#line 866 "parse.y"
     {
                        Symbol *s = addsym((yyvsp[(1) - (1)].name));
                        if(s->stype != SValue)
@@ -2467,7 +2467,7 @@ yyreduce:
     break;
 
   case 130:
-#line 877 "heimdal/lib/asn1/parse.y"
+#line 877 "parse.y"
     {
                        (yyval.value) = emalloc(sizeof(*(yyval.value)));
                        (yyval.value)->type = stringvalue;
@@ -2476,7 +2476,7 @@ yyreduce:
     break;
 
   case 131:
-#line 885 "heimdal/lib/asn1/parse.y"
+#line 885 "parse.y"
     {
                        (yyval.value) = emalloc(sizeof(*(yyval.value)));
                        (yyval.value)->type = booleanvalue;
@@ -2485,7 +2485,7 @@ yyreduce:
     break;
 
   case 132:
-#line 891 "heimdal/lib/asn1/parse.y"
+#line 891 "parse.y"
     {
                        (yyval.value) = emalloc(sizeof(*(yyval.value)));
                        (yyval.value)->type = booleanvalue;
@@ -2494,7 +2494,7 @@ yyreduce:
     break;
 
   case 133:
-#line 899 "heimdal/lib/asn1/parse.y"
+#line 899 "parse.y"
     {
                        (yyval.value) = emalloc(sizeof(*(yyval.value)));
                        (yyval.value)->type = integervalue;
@@ -2503,13 +2503,13 @@ yyreduce:
     break;
 
   case 135:
-#line 910 "heimdal/lib/asn1/parse.y"
+#line 910 "parse.y"
     {
                }
     break;
 
   case 136:
-#line 915 "heimdal/lib/asn1/parse.y"
+#line 915 "parse.y"
     {
                        (yyval.value) = emalloc(sizeof(*(yyval.value)));
                        (yyval.value)->type = objectidentifiervalue;
@@ -2519,7 +2519,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 2523 "heimdal/lib/asn1/parse.y"
+#line 2523 "parse.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2733,7 +2733,7 @@ yyreturn:
 }
 
 
-#line 922 "heimdal/lib/asn1/parse.y"
+#line 922 "parse.y"
 
 
 void
index bea506ca7b984ab873e6cae8128e8c1a1a833d24..5e73094f9e6b2a1833f6d12a411c710437bc7d96 100644 (file)
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 65 "heimdal/lib/asn1/parse.y"
+#line 65 "parse.y"
 {
     int constant;
     struct value *value;
@@ -238,7 +238,7 @@ typedef union YYSTYPE
     struct constraint_spec *constraint_spec;
 }
 /* Line 1489 of yacc.c.  */
-#line 242 "heimdal/lib/asn1/parse.y"
+#line 242 "parse.h"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index 1bfc11ad740f362539094b45307fdec0388a2c3e..989b26581b3a1b69eea569b96e37bbef624da33a 100644 (file)
@@ -2,7 +2,7 @@
 
 PKINIT DEFINITIONS ::= BEGIN
 
-IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
+IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum, Ticket FROM krb5
        IssuerAndSerialNumber, ContentInfo FROM cms
        SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
        heim_any FROM heim;
@@ -40,6 +40,11 @@ td-dh-parameters INTEGER ::=             109
 
 DHNonce ::= OCTET STRING
 
+KDFAlgorithmId ::= SEQUENCE {
+       kdf-id            [0] OBJECT IDENTIFIER,
+       ...
+}
+
 TrustedCA ::= SEQUENCE {
        caName                  [0] IMPLICIT OCTET STRING,
        certificateSerialNumber [1] INTEGER OPTIONAL,
@@ -76,6 +81,8 @@ AuthPack ::= SEQUENCE {
        clientPublicValue       [1] SubjectPublicKeyInfo OPTIONAL,
        supportedCMSTypes       [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
        clientDHNonce           [3] DHNonce OPTIONAL,
+       ...,
+       supportedKDFs           [4] SEQUENCE OF KDFAlgorithmId OPTIONAL,
        ...
 }
 
@@ -89,10 +96,12 @@ KRB5PrincipalName ::= SEQUENCE {
 
 AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier
 
-
 DHRepInfo ::= SEQUENCE {
        dhSignedData            [0] IMPLICIT OCTET STRING,
-       serverDHNonce           [1] DHNonce OPTIONAL
+       serverDHNonce           [1] DHNonce OPTIONAL,
+       ...,
+       kdf                     [2] KDFAlgorithmId OPTIONAL,
+       ...
 }
 
 PA-PK-AS-REP ::= CHOICE {
@@ -162,4 +171,12 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
        ...
 }
 
+PkinitSuppPubInfo ::= SEQUENCE {
+       enctype           [0] INTEGER (-2147483648..2147483647),
+       as-REQ            [1] OCTET STRING,
+       pk-as-rep         [2] OCTET STRING,
+       ticket            [3] Ticket,
+       ...
+}
+
 END
index 0ec3b695ebebeb9c50a6015e9e25c4f226bf2f1a..8e24f0740b8a6b6f5a1f70b4bb4e4fcd37c484b8 100644 (file)
@@ -21,6 +21,8 @@ id-pkcs1-sha256WithRSAEncryption OBJECT IDENTIFIER ::=        { id-pkcs-1 11 }
 id-pkcs1-sha384WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 12 }
 id-pkcs1-sha512WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 13 }
 
+id-heim-rsa-pkcs1-x509 OBJECT IDENTIFIER ::= { 1  2 752 43 16 1 }
+
 id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
        rsadsi(113549) pkcs(1) 2 }
 id-pkcs2-md2 OBJECT IDENTIFIER ::=             { id-pkcs-2 2 }
index 7a85b302a11bcb80cab551a11c2ebe2acf9bbb88..3c6ea3beb71dfa4a8e78a718bfcb93c0c1234d3d 100644 (file)
@@ -1,6 +1,5 @@
-#include "config.h"
 
-#line 3 "heimdal/lib/com_err/lex.c"
+#line 3 "lex.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -524,7 +523,7 @@ char *yytext;
 #include "parse.h"
 #include "lex.h"
 
-RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $");
+RCSID("$Id: lex.l 15143 2005-05-16 08:52:54Z lha $");
 
 static unsigned lineno = 1;
 static int getstring(void);
@@ -533,7 +532,7 @@ static int getstring(void);
 
 #undef ECHO
 
-#line 536 "heimdal/lib/com_err/lex.c"
+#line 536 "lex.c"
 
 #define INITIAL 0
 
@@ -551,6 +550,35 @@ static int getstring(void);
 
 static int yy_init_globals (void );
 
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * out_str  );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number  );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -688,7 +716,7 @@ YY_DECL
     
 #line 59 "lex.l"
 
-#line 691 "heimdal/lib/com_err/lex.c"
+#line 720 "lex.c"
 
        if ( !(yy_init) )
                {
@@ -852,7 +880,7 @@ YY_RULE_SETUP
 #line 75 "lex.l"
 ECHO;
        YY_BREAK
-#line 855 "heimdal/lib/com_err/lex.c"
+#line 884 "lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -1083,7 +1111,7 @@ static int yy_get_next_buffer (void)
 
                /* Read in more data. */
                YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), (size_t) num_to_read );
+                       (yy_n_chars), num_to_read );
 
                YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
                }
@@ -1584,7 +1612,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 
 /** Setup the input buffer state to scan a string. The next call to yylex() will
  * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
+ * @param str a NUL-terminated string to scan
  * 
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
index 95fe18f16e4dabf25a69a4267c7513d6be31e6d6..4bacb721ca112acfb3bab591a2ece14f16737d4b 100644 (file)
@@ -90,7 +90,7 @@
 
 
 /* Copy the first part of user declarations.  */
-#line 1 "heimdal/lib/com_err/parse.y"
+#line 1 "parse.y"
 
 /*
  * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
@@ -163,13 +163,13 @@ extern char *yytext;
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 53 "heimdal/lib/com_err/parse.y"
+#line 53 "parse.y"
 {
   char *string;
   int number;
 }
 /* Line 187 of yacc.c.  */
-#line 173 "heimdal/lib/com_err/parse.y"
+#line 173 "parse.c"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -182,7 +182,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 186 "heimdal/lib/com_err/parse.y"
+#line 186 "parse.c"
 
 #ifdef short
 # undef short
@@ -1381,14 +1381,14 @@ yyreduce:
   switch (yyn)
     {
         case 6:
-#line 73 "heimdal/lib/com_err/parse.y"
+#line 73 "parse.y"
     {
                    id_str = (yyvsp[(2) - (2)].string);
                }
     break;
 
   case 7:
-#line 79 "heimdal/lib/com_err/parse.y"
+#line 79 "parse.y"
     {
                    base_id = name2number((yyvsp[(2) - (2)].string));
                    strlcpy(name, (yyvsp[(2) - (2)].string), sizeof(name));
@@ -1397,7 +1397,7 @@ yyreduce:
     break;
 
   case 8:
-#line 85 "heimdal/lib/com_err/parse.y"
+#line 85 "parse.y"
     {
                    base_id = name2number((yyvsp[(2) - (3)].string));
                    strlcpy(name, (yyvsp[(3) - (3)].string), sizeof(name));
@@ -1407,14 +1407,14 @@ yyreduce:
     break;
 
   case 11:
-#line 98 "heimdal/lib/com_err/parse.y"
+#line 98 "parse.y"
     {
                        number = (yyvsp[(2) - (2)].number);
                }
     break;
 
   case 12:
-#line 102 "heimdal/lib/com_err/parse.y"
+#line 102 "parse.y"
     {
                    free(prefix);
                    asprintf (&prefix, "%s_", (yyvsp[(2) - (2)].string));
@@ -1425,7 +1425,7 @@ yyreduce:
     break;
 
   case 13:
-#line 110 "heimdal/lib/com_err/parse.y"
+#line 110 "parse.y"
     {
                    prefix = realloc(prefix, 1);
                    if (prefix == NULL)
@@ -1435,7 +1435,7 @@ yyreduce:
     break;
 
   case 14:
-#line 117 "heimdal/lib/com_err/parse.y"
+#line 117 "parse.y"
     {
                    struct error_code *ec = malloc(sizeof(*ec));
                    
@@ -1458,7 +1458,7 @@ yyreduce:
     break;
 
   case 15:
-#line 137 "heimdal/lib/com_err/parse.y"
+#line 137 "parse.y"
     {
                        YYACCEPT;
                }
@@ -1466,7 +1466,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 1470 "heimdal/lib/com_err/parse.y"
+#line 1470 "parse.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1680,7 +1680,7 @@ yyreturn:
 }
 
 
-#line 142 "heimdal/lib/com_err/parse.y"
+#line 142 "parse.y"
 
 
 static long
index 9aabca90236f4b732d92c6930a159af8e4e3c553..4c9681ff34f5aaa6e6a84c5b39285fcd5feb2a20 100644 (file)
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 53 "heimdal/lib/com_err/parse.y"
+#line 53 "parse.y"
 {
   char *string;
   int number;
 }
 /* Line 1489 of yacc.c.  */
-#line 74 "heimdal/lib/com_err/parse.y"
+#line 74 "parse.h"
        YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index cca529fe26ff5c9e1f43f9a34e436728ce7f24b7..2223f4f22f778f916d6e36fb3c4ee4b761785c68 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gssapi_krb5.h 20385 2007-04-18 08:51:32Z lha $ */
+/* $Id: gssapi_krb5.h 22655 2008-02-26 12:40:35Z lha $ */
 
 #ifndef GSSAPI_KRB5_H_
 #define GSSAPI_KRB5_H_
@@ -80,6 +80,7 @@ extern gss_OID GSS_KRB5_GET_SERVICE_KEYBLOCK_X;
 /* Extensions creds */
 extern gss_OID GSS_KRB5_IMPORT_CRED_X;
 extern gss_OID GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X;
+extern gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X;
 
 /*
  * kerberos mechanism specific functions
index 403990ad47a1d68087bdb873feda43585d3af38d..b360de13fcaf53192de49fc62d6c719ef72610cb 100644 (file)
@@ -356,4 +356,6 @@ gssapi_mech_interface __gss_spnego_initialize(void);
 gssapi_mech_interface __gss_krb5_initialize(void);
 gssapi_mech_interface __gss_ntlm_initialize(void);
 
+void           gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32);
+
 #endif /* GSSAPI_MECH_H */
index d5c70636bc5824f9834fa8232494d460e65c4765..051446c19b4d4e09bc32f2b048816ce1106d7647 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: acquire_cred.c 21221 2007-06-20 08:42:10Z lha $");
+RCSID("$Id: acquire_cred.c 22596 2008-02-18 18:05:55Z lha $");
 
 OM_uint32
 __gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
@@ -128,9 +128,12 @@ static OM_uint32 acquire_initiator_cred
     ret = GSS_S_FAILURE;
     memset(&cred, 0, sizeof(cred));
 
-    /* If we have a preferred principal, lets try to find it in all
-     * caches, otherwise, fall back to default cache.  Ignore
-     * errors. */
+    /* 
+     * If we have a preferred principal, lets try to find it in all
+     * caches, otherwise, fall back to default cache, ignore all
+     * errors while searching.
+     */
+
     if (handle->principal)
        kret = krb5_cc_cache_match (context,
                                    handle->principal,
@@ -142,32 +145,30 @@ static OM_uint32 acquire_initiator_cred
        if (kret)
            goto end;
     }
-    kret = krb5_cc_get_principal(context, ccache,
-       &def_princ);
+    kret = krb5_cc_get_principal(context, ccache, &def_princ);
     if (kret != 0) {
        /* we'll try to use a keytab below */
-       krb5_cc_destroy(context, ccache);
-       ccache = NULL;
+       krb5_cc_close(context, ccache);
+       def_princ = NULL;
        kret = 0;
     } else if (handle->principal == NULL)  {
-       kret = krb5_copy_principal(context, def_princ,
-           &handle->principal);
+       kret = krb5_copy_principal(context, def_princ, &handle->principal);
        if (kret)
            goto end;
     } else if (handle->principal != NULL &&
-       krb5_principal_compare(context, handle->principal,
-       def_princ) == FALSE) {
-       /* Before failing, lets check the keytab */
+              krb5_principal_compare(context, handle->principal,
+                                     def_princ) == FALSE) {
        krb5_free_principal(context, def_princ);
        def_princ = NULL;
+       krb5_cc_close(context, ccache);
+       ccache = NULL;
     }
     if (def_princ == NULL) {
        /* We have no existing credentials cache,
         * so attempt to get a TGT using a keytab.
         */
        if (handle->principal == NULL) {
-           kret = krb5_get_default_principal(context,
-               &handle->principal);
+           kret = krb5_get_default_principal(context, &handle->principal);
            if (kret)
                goto end;
        }
@@ -182,16 +183,19 @@ static OM_uint32 acquire_initiator_cred
        krb5_get_init_creds_opt_free(context, opt);
        if (kret)
            goto end;
-       kret = krb5_cc_gen_new(context, &krb5_mcc_ops,
-               &ccache);
+       kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
        if (kret)
            goto end;
        kret = krb5_cc_initialize(context, ccache, cred.client);
-       if (kret)
+       if (kret) {
+           krb5_cc_destroy(context, ccache);
            goto end;
+       }
        kret = krb5_cc_store_cred(context, ccache, &cred);
-       if (kret)
+       if (kret) {
+           krb5_cc_destroy(context, ccache);
            goto end;
+       }
        handle->lifetime = cred.times.endtime;
        handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
     } else {
@@ -201,8 +205,10 @@ static OM_uint32 acquire_initiator_cred
                                        ccache,
                                        handle->principal,
                                        &handle->lifetime);
-       if (ret != GSS_S_COMPLETE)
+       if (ret != GSS_S_COMPLETE) {
+           krb5_cc_close(context, ccache);
            goto end;
+       }
        kret = 0;
     }
 
@@ -216,13 +222,8 @@ end:
        krb5_free_principal(context, def_princ);
     if (keytab != NULL)
        krb5_kt_close(context, keytab);
-    if (ret != GSS_S_COMPLETE) {
-       if (ccache != NULL)
-           krb5_cc_close(context, ccache);
-       if (kret != 0) {
-           *minor_status = kret;
-       }
-    }
+    if (ret != GSS_S_COMPLETE && kret != 0)
+       *minor_status = kret;
     return (ret);
 }
 
@@ -257,8 +258,23 @@ static OM_uint32 acquire_acceptor_cred
            goto end;
        krb5_kt_free_entry(context, &entry);
        ret = GSS_S_COMPLETE;
-    }
+    } else {
+       /* 
+        * Check if there is at least one entry in the keytab before
+        * declaring it as an useful keytab.
+        */
+       krb5_keytab_entry tmp;
+       krb5_kt_cursor c;
+
+       kret = krb5_kt_start_seq_get (context, handle->keytab, &c);
+       if (kret)
+           goto end;
+       if (krb5_kt_next_entry(context, handle->keytab, &tmp, &c) == 0) {
+           krb5_kt_free_entry(context, &tmp);
+           ret = GSS_S_COMPLETE; /* ok found one entry */
+       }
+       krb5_kt_end_seq_get (context, handle->keytab, &c);
+    } 
 end:
     if (ret != GSS_S_COMPLETE) {
        if (handle->keytab != NULL)
index d4c1bc4db299d00d0a346ba9b3a322f1824d14dc..03fe61dc5744f772dfd98934d08d16b97aa92fa2 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5/gsskrb5_locl.h"
 #include <gssapi_mech.h>
 
-RCSID("$Id: external.c 20386 2007-04-18 08:52:08Z lha $");
+RCSID("$Id: external.c 22128 2007-12-04 00:56:55Z lha $");
 
 /*
  * The implementation must reserve static storage for a
@@ -374,8 +374,6 @@ gss_OID GSS_SASL_DIGEST_MD5_MECHANISM = &gss_sasl_digest_md5_mechanism_desc;
  * Context for krb5 calls.
  */
 
-krb5_context context;
-
 /*
  *
  */
index c2239f1346258876f6db00427f46b8d033fa6c53..64a0dd36b19d9cd6d0ed083915ac6a6f4a9a266a 100644 (file)
@@ -413,7 +413,7 @@ _gsskrb5_init (krb5_context */*context*/);
 OM_uint32
 _gsskrb5_init_sec_context (
        OM_uint32 * /*minor_status*/,
-       const gss_cred_id_t /*initiator_cred_handle*/,
+       const gss_cred_id_t /*cred_handle*/,
        gss_ctx_id_t * /*context_handle*/,
        const gss_name_t /*target_name*/,
        const gss_OID /*mech_type*/,
index 6ffb6070352fc85c512375fd3509645f76c6a209..3e8c1b8fa65de5d7952a343478b037f24b183c32 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gsskrb5_locl.h 20324 2007-04-12 16:46:01Z lha $ */
+/* $Id: gsskrb5_locl.h 22655 2008-02-26 12:40:35Z lha $ */
 
 #ifndef GSSKRB5_LOCL_H
 #define GSSKRB5_LOCL_H
@@ -86,6 +86,7 @@ typedef struct {
   krb5_principal principal;
   int cred_flags;
 #define GSS_CF_DESTROY_CRED_ON_RELEASE 1
+#define GSS_CF_NO_CI_FLAGS             2
   struct krb5_keytab_data *keytab;
   OM_uint32 lifetime;
   gss_cred_usage_t usage;
index 4d1ae0daa9f9042236e472b248a256a554f8bf9b..d4482a54b275243ca8414d4c069c001c42544b4a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: init_sec_context.c 20326 2007-04-12 16:49:57Z lha $");
+RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $");
 
 /*
  * copy the addresses from `input_chan_bindings' (if any) to
@@ -326,7 +326,7 @@ do_delegation (krb5_context context,
 static OM_uint32
 init_auth
 (OM_uint32 * minor_status,
- gsskrb5_cred initiator_cred_handle,
+ gsskrb5_cred cred,
  gsskrb5_ctx ctx,
  krb5_context context,
  krb5_const_principal name,
@@ -344,7 +344,7 @@ init_auth
     OM_uint32 ret = GSS_S_FAILURE;
     krb5_error_code kret;
     krb5_flags ap_options;
-    krb5_creds *cred = NULL;
+    krb5_creds *kcred = NULL;
     krb5_data outbuf;
     krb5_ccache ccache = NULL;
     uint32_t flags;
@@ -362,7 +362,7 @@ init_auth
     if (actual_mech_type)
        *actual_mech_type = GSS_KRB5_MECHANISM;
 
-    if (initiator_cred_handle == NULL) {
+    if (cred == NULL) {
        kret = krb5_cc_default (context, &ccache);
        if (kret) {
            *minor_status = kret;
@@ -370,7 +370,7 @@ init_auth
            goto failure;
        }
     } else
-       ccache = initiator_cred_handle->ccache;
+       ccache = cred->ccache;
 
     kret = krb5_cc_get_principal (context, ccache, &ctx->source);
     if (kret) {
@@ -400,8 +400,8 @@ init_auth
     {
        krb5_enctype *enctypes = NULL;
 
-       if (initiator_cred_handle && initiator_cred_handle->enctypes)
-           enctypes = initiator_cred_handle->enctypes;
+       if (cred && cred->enctypes)
+           enctypes = cred->enctypes;
        krb5_set_default_in_tkt_etypes(context, enctypes);
     }
 
@@ -412,11 +412,11 @@ init_auth
                            ctx->target,
                            time_req,
                            time_rec,
-                           &cred);
+                           &kcred);
     if (ret)
        goto failure;
 
-    ctx->lifetime = cred->times.endtime;
+    ctx->lifetime = kcred->times.endtime;
 
     ret = _gsskrb5_lifetime_left(minor_status,
                                 context,
@@ -434,11 +434,11 @@ init_auth
 
     krb5_auth_con_setkey(context, 
                         ctx->auth_context, 
-                        &cred->session);
+                        &kcred->session);
 
     kret = krb5_auth_con_generatelocalsubkey(context, 
                                             ctx->auth_context,
-                                            &cred->session);
+                                            &kcred->session);
     if(kret) {
        *minor_status = kret;
        ret = GSS_S_FAILURE;
@@ -449,10 +449,10 @@ init_auth
      * If the credential doesn't have ok-as-delegate, check what local
      * policy say about ok-as-delegate, default is FALSE that makes
      * code ignore the KDC setting and follow what the application
-     * requested. If its TRUE, strip of the GSS_C_DELEG_FLAG if the
+     * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the
      * KDC doesn't set ok-as-delegate.
      */
-    if (!cred->flags.b.ok_as_delegate) {
+    if (!kcred->flags.b.ok_as_delegate) {
        krb5_boolean delegate;
     
        krb5_appdefault_boolean(context,
@@ -467,7 +467,7 @@ init_auth
     if (req_flags & GSS_C_DELEG_FLAG)
        do_delegation (context,
                       ctx->auth_context,
-                      ccache, cred, name, &fwd_data, &flags);
+                      ccache, kcred, name, &fwd_data, &flags);
     
     if (req_flags & GSS_C_MUTUAL_FLAG) {
        flags |= GSS_C_MUTUAL_FLAG;
@@ -490,8 +490,10 @@ init_auth
     if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)
        flags |= GSS_C_EXTENDED_ERROR_FLAG;
 
-    flags |= GSS_C_CONF_FLAG;
-    flags |= GSS_C_INTEG_FLAG;
+    if (cred == NULL || !(cred->cred_flags & GSS_CF_NO_CI_FLAGS)) {
+       flags |= GSS_C_CONF_FLAG;
+       flags |= GSS_C_INTEG_FLAG;
+    }
     flags |= GSS_C_TRANS_FLAG;
     
     if (ret_flags)
@@ -513,7 +515,7 @@ init_auth
     kret = krb5_build_authenticator (context,
                                     ctx->auth_context,
                                     enctype,
-                                    cred,
+                                    kcred,
                                     &cksum,
                                     NULL,
                                     &authenticator,
@@ -527,7 +529,7 @@ init_auth
 
     kret = krb5_build_ap_req (context,
                              enctype,
-                             cred,
+                             kcred,
                              ap_options,
                              authenticator,
                              &outbuf);
@@ -544,9 +546,9 @@ init_auth
        goto failure;
 
     krb5_data_free (&outbuf);
-    krb5_free_creds(context, cred);
+    krb5_free_creds(context, kcred);
     free_Checksum(&cksum);
-    if (initiator_cred_handle == NULL)
+    if (cred == NULL)
        krb5_cc_close(context, ccache);
 
     if (flags & GSS_C_MUTUAL_FLAG) {
@@ -556,9 +558,9 @@ init_auth
 
     return gsskrb5_initiator_ready(minor_status, ctx, context);
 failure:
-    if(cred)
-       krb5_free_creds(context, cred);
-    if (ccache && initiator_cred_handle == NULL)
+    if(kcred)
+       krb5_free_creds(context, kcred);
+    if (ccache && cred == NULL)
        krb5_cc_close(context, ccache);
 
     return ret;
@@ -682,7 +684,7 @@ repl_mutual
 
 OM_uint32 _gsskrb5_init_sec_context
 (OM_uint32 * minor_status,
- const gss_cred_id_t initiator_cred_handle,
+ const gss_cred_id_t cred_handle,
  gss_ctx_id_t * context_handle,
  const gss_name_t target_name,
  const gss_OID mech_type,
@@ -697,7 +699,7 @@ OM_uint32 _gsskrb5_init_sec_context
     )
 {
     krb5_context context;
-    gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
+    gsskrb5_cred cred = (gsskrb5_cred)cred_handle;
     krb5_const_principal name = (krb5_const_principal)target_name;
     gsskrb5_ctx ctx;
     OM_uint32 ret;
index d0ca1c4d95ddf779ebc3969a2c02a0669c2d24c0..242dfa87b476982e967b2fb1acbbcdf5d30dc987 100644 (file)
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: set_cred_option.c 20325 2007-04-12 16:49:17Z lha $");
+RCSID("$Id: set_cred_option.c 22655 2008-02-26 12:40:35Z lha $");
 
+/* 1.2.752.43.13.17 */
+static gss_OID_desc gss_krb5_ccache_name_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
+
+gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_ccache_name_x_oid_desc;
+
+/* 1.2.752.43.13.18 */
 static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
-{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
 
 gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
 
+
+
 static OM_uint32
 import_cred(OM_uint32 *minor_status,
            krb5_context context,
@@ -201,6 +210,27 @@ out:
     return major_stat;
 }
 
+static OM_uint32
+no_ci_flags(OM_uint32 *minor_status,
+           krb5_context context,
+           gss_cred_id_t *cred_handle,
+           const gss_buffer_t value)
+{
+    gsskrb5_cred cred;
+
+    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+       *minor_status = 0;
+       return GSS_S_FAILURE;
+    }
+
+    cred = (gsskrb5_cred)*cred_handle;
+    cred->cred_flags |= GSS_CF_NO_CI_FLAGS;
+       
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+
+}
+
 
 OM_uint32
 _gsskrb5_set_cred_option
@@ -224,6 +254,11 @@ _gsskrb5_set_cred_option
     if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X))
        return allowed_enctypes(minor_status, context, cred_handle, value);
 
+    if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) {
+       return no_ci_flags(minor_status, context, cred_handle, value);
+    }
+       
+
     *minor_status = EINVAL;
     return GSS_S_FAILURE;
 }
index e4517bee449cbcb364d4997c7b141ee22a130813..926630c42dcd0c41742ec73c39c6102ba3a2d5e6 100644 (file)
@@ -1,7 +1,7 @@
 #include "mech/mech_locl.h"
 #include "heim_threads.h"
 
-RCSID("$Id: context.c 21248 2007-06-21 00:45:13Z lha $");
+RCSID("$Id: context.c 22600 2008-02-21 12:46:24Z lha $");
 
 struct mg_thread_ctx {
     gss_OID mech;
@@ -107,6 +107,13 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
     OM_uint32 message_content;
     struct mg_thread_ctx *mg;
 
+    /* 
+     * Mechs without gss_display_status() does
+     * gss_mg_collect_error() by themself.
+     */
+    if (m->gm_display_status == NULL)
+       return ;
+
     mg = _gss_mechglue_thread();
     if (mg == NULL)
        return;
@@ -139,3 +146,12 @@ _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
        mg->min_error.length = 0;
     }
 }
+
+void
+gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)
+{
+    gssapi_mech_interface m = __gss_get_mechanism(mech);
+    if (m == NULL)
+       return;
+    _gss_mg_error(m, maj, min);
+}
index d1e243d8b854a16c47a8ece08b8024e5ca700b5b..a6b1ded5cad50141e959fab969f8903432ebd462 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_accept_sec_context.c 21237 2007-06-20 11:21:09Z lha $");
+RCSID("$Id: gss_accept_sec_context.c 22071 2007-11-14 20:04:50Z lha $");
 
 static OM_uint32
 parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
@@ -38,7 +38,7 @@ parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
        
        /*
         * Token must start with [APPLICATION 0] SEQUENCE.
-        * But if it doesn't assume its DCE-STYLE Kerberos!
+        * But if it doesn't assume it is DCE-STYLE Kerberos!
         */
        if (len == 0)
                return (GSS_S_DEFECTIVE_TOKEN);
@@ -102,7 +102,7 @@ choose_mech(const gss_buffer_t input, gss_OID mech_oid)
        OM_uint32 status;
 
        /*
-        * First try to parse the gssapi token header and see if its a
+        * First try to parse the gssapi token header and see if it's a
         * correct header, use that in the first hand.
         */
 
index 9e77f429828e1be63a73be0cb212adff807253c3..03081cb70ffe906262a4c2436b21456a1a221dc8 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_krb5.c 21123 2007-06-18 20:05:26Z lha $");
+RCSID("$Id: gss_krb5.c 21889 2007-08-09 07:43:24Z lha $");
 
 #include <krb5.h>
 #include <roken.h>
@@ -253,7 +253,6 @@ free_key(gss_krb5_lucid_key_t *key)
     memset(key, 0, sizeof(*key));
 }
 
-
 OM_uint32
 gss_krb5_export_lucid_sec_context(OM_uint32 *minor_status,
                                  gss_ctx_id_t *context_handle,
@@ -824,3 +823,43 @@ gsskrb5_set_default_realm(const char *realm)
 
        return (GSS_S_COMPLETE);
 }
+
+OM_uint32
+gss_krb5_get_tkt_flags(OM_uint32 *minor_status,
+                      gss_ctx_id_t context_handle,
+                      OM_uint32 *tkt_flags)
+{
+
+    OM_uint32 major_status;
+    gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+
+    if (context_handle == GSS_C_NO_CONTEXT) {
+       *minor_status = EINVAL;
+       return GSS_S_FAILURE;
+    }
+    
+    major_status =
+       gss_inquire_sec_context_by_oid (minor_status,
+                                       context_handle,
+                                       GSS_KRB5_GET_TKT_FLAGS_X,
+                                       &data_set);
+    if (major_status)
+       return major_status;
+    
+    if (data_set == GSS_C_NO_BUFFER_SET || 
+       data_set->count != 1 ||
+       data_set->elements[0].length < 4) {
+       gss_release_buffer_set(minor_status, &data_set);
+       *minor_status = EINVAL;
+       return GSS_S_FAILURE;
+    }
+
+    {
+       const u_char *p = data_set->elements[0].value;
+       *tkt_flags = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+    }
+
+    gss_release_buffer_set(minor_status, &data_set);
+    return GSS_S_COMPLETE;
+}
+
index f1a18afb13a65cf77dad28737f02f0977e272296..fe65ad1ae15561c0b309b3b10dd3eb55daa3bcd7 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "mech_locl.h"
 #include <heim_threads.h>
-RCSID("$Id: gss_mech_switch.c 21700 2007-07-26 19:08:34Z lha $");
+RCSID("$Id: gss_mech_switch.c 21698 2007-07-26 19:07:11Z lha $");
 
 #ifndef _PATH_GSS_MECH
 #define _PATH_GSS_MECH "/etc/gss/mech"
index 4372e622948b2bf0efd28acb599138360cecd102..388cfdbf4cfa0012b13085ee4348040255ac6675 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mech_locl.h"
-RCSID("$Id: gss_release_oid_set.c 19963 2007-01-17 16:01:22Z lha $");
+RCSID("$Id: gss_release_oid_set.c 22144 2007-12-04 17:31:55Z lha $");
 
 OM_uint32
 gss_release_oid_set(OM_uint32 *minor_status,
@@ -35,7 +35,7 @@ gss_release_oid_set(OM_uint32 *minor_status,
 {
 
        *minor_status = 0;
-       if (*set) {
+       if (set && *set) {
                if ((*set)->elements)
                        free((*set)->elements);
                free(*set);
index 1afe26f1e39dae042c68a37f69fa792a49a8efa9..df25b0f4bf61c76570c2de575f03ad118661cc2b 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: accept_sec_context.c 21461 2007-07-10 14:01:13Z lha $");
+RCSID("$Id: accept_sec_context.c 22600 2008-02-21 12:46:24Z lha $");
 
 static OM_uint32
 send_reject (OM_uint32 *minor_status,
@@ -540,7 +540,7 @@ acceptor_start
            gss_cred_id_t *delegated_cred_handle
           )
 {
-    OM_uint32 ret, junk, minor;
+    OM_uint32 ret, junk;
     NegotiationToken nt;
     size_t nt_len;
     NegTokenInit *ni;
@@ -609,7 +609,7 @@ acceptor_start
     /*
      * First we try the opportunistic token if we have support for it,
      * don't try to verify we have credential for the token,
-     * gss_accept_sec_context will (hopefully) tell us that.
+     * gss_accept_sec_context() will (hopefully) tell us that.
      * If that failes, 
      */
 
@@ -633,12 +633,12 @@ acceptor_start
            mech_cred = GSS_C_NO_CREDENTIAL;
        
        if (ctx->mech_src_name != GSS_C_NO_NAME)
-           gss_release_name(&minor, &ctx->mech_src_name);
+           gss_release_name(&junk, &ctx->mech_src_name);
        
        if (ctx->delegated_cred_id != GSS_C_NO_CREDENTIAL)
-           _gss_spnego_release_cred(&minor, &ctx->delegated_cred_id);
+           _gss_spnego_release_cred(&junk, &ctx->delegated_cred_id);
        
-       ret = gss_accept_sec_context(&minor,
+       ret = gss_accept_sec_context(minor_status,
                                     &ctx->negotiated_ctx_id,
                                     mech_cred,
                                     mech_input_token,
@@ -656,7 +656,7 @@ acceptor_start
                ctx->open = 1;
 
            if (mech_delegated_cred && delegated_cred_handle)
-               ret = _gss_spnego_alloc_cred(minor_status,
+               ret = _gss_spnego_alloc_cred(&junk,
                                             mech_delegated_cred,
                                             delegated_cred_handle);
            else
@@ -674,6 +674,8 @@ acceptor_start
                goto out;
 
            first_ok = 1;
+       } else {
+           gss_mg_collect_error(preferred_mech_type, ret, *minor_status);
        }
     }
 
@@ -681,7 +683,9 @@ acceptor_start
      * If opportunistic token failed, lets try the other mechs.
      */
 
-    if (!first_ok) {
+    if (!first_ok && ni->mechToken != NULL) {
+
+       preferred_mech_type = GSS_C_NO_OID;
 
        /* Call glue layer to find first mech we support */
        for (i = 1; i < ni->mechTypes.len; ++i) {
@@ -695,7 +699,7 @@ acceptor_start
        if (preferred_mech_type == GSS_C_NO_OID) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            free_NegotiationToken(&nt);
-           return GSS_S_BAD_MECH;
+           return ret;
        }
 
        ctx->preferred_mech_type = preferred_mech_type;
@@ -717,7 +721,7 @@ acceptor_start
     
 out:
     if (mech_output_token.value != NULL)
-       gss_release_buffer(&minor, &mech_output_token);
+       gss_release_buffer(&junk, &mech_output_token);
     if (mech_buf.value != NULL) {
        free(mech_buf.value);
        mech_buf.value = NULL;
@@ -754,7 +758,7 @@ out:
        return ret;
     }
 
-    _gss_spnego_internal_delete_sec_context(&minor, context_handle,
+    _gss_spnego_internal_delete_sec_context(&junk, context_handle,
                                            GSS_C_NO_BUFFER);
     
     return ret;
@@ -877,6 +881,7 @@ acceptor_continue
            }
            if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
                free_NegotiationToken(&nt);
+               gss_mg_collect_error(ctx->negotiated_mech_type, ret, minor);
                send_reject (minor_status, output_token);
                HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
                return ret;
index bc7da9410e6a71317e7f65d3a8300353c2005afd..287f4f760ed76871241cf41d1dd5404f4dca07c0 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: compat.c 19415 2006-12-18 17:52:26Z lha $");
+RCSID("$Id: compat.c 21866 2007-08-08 11:31:29Z lha $");
 
 /*
  * Apparently Microsoft got the OID wrong, and used
@@ -129,6 +129,7 @@ OM_uint32 _gss_spnego_internal_delete_sec_context
     gss_release_oid(&minor, &ctx->preferred_mech_type);
     ctx->negotiated_mech_type = GSS_C_NO_OID;
 
+    gss_release_name(&minor, &ctx->target_name);
     gss_release_name(&minor, &ctx->mech_src_name);
 
     if (ctx->negotiated_ctx_id != GSS_C_NO_CONTEXT) {
index 3535c7bb3596cb782b0fe745eb5fd1ad8478d529..0169017ee5af9de3bff86d5b3db2fad233ee76ac 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: context_stubs.c 21035 2007-06-09 15:32:47Z lha $");
+RCSID("$Id: context_stubs.c 22604 2008-02-21 21:12:48Z lha $");
 
 static OM_uint32
 spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
@@ -263,18 +263,6 @@ OM_uint32 _gss_spnego_unwrap
                      qop_state);
 }
 
-OM_uint32 _gss_spnego_display_status
-           (OM_uint32 * minor_status,
-            OM_uint32 status_value,
-            int status_type,
-            const gss_OID mech_type,
-            OM_uint32 * message_context,
-            gss_buffer_t status_string
-           )
-{
-    return GSS_S_FAILURE;
-}
-
 OM_uint32 _gss_spnego_compare_name
            (OM_uint32 *minor_status,
             const gss_name_t name1,
@@ -406,28 +394,58 @@ OM_uint32 _gss_spnego_inquire_context (
            )
 {
     gssspnego_ctx ctx;
+    OM_uint32 maj_stat, junk;
+    gss_name_t src_mn, targ_mn;
 
     *minor_status = 0;
 
-    if (context_handle == GSS_C_NO_CONTEXT) {
+    if (context_handle == GSS_C_NO_CONTEXT)
        return GSS_S_NO_CONTEXT;
-    }
 
     ctx = (gssspnego_ctx)context_handle;
 
-    if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
+    if (ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT)
        return GSS_S_NO_CONTEXT;
-    }
 
-    return gss_inquire_context(minor_status,
-                              ctx->negotiated_ctx_id,
-                              src_name,
-                              targ_name,
-                              lifetime_rec,
-                              mech_type,
-                              ctx_flags,
-                              locally_initiated,
-                              open_context);
+    maj_stat = gss_inquire_context(minor_status,
+                                  ctx->negotiated_ctx_id,
+                                  &src_mn,
+                                  &targ_mn,
+                                  lifetime_rec,
+                                  mech_type,
+                                  ctx_flags,
+                                  locally_initiated,
+                                  open_context);
+    if (maj_stat != GSS_S_COMPLETE)
+       return maj_stat;
+
+    if (src_name) {
+       spnego_name name = calloc(1, sizeof(*name));
+       if (name == NULL)
+           goto enomem;
+       name->mech = src_mn;
+       *src_name = (gss_name_t)name;
+    } else
+       gss_release_name(&junk, &src_mn);
+    
+    if (targ_name) {
+       spnego_name name = calloc(1, sizeof(*name));
+       if (name == NULL) {
+           gss_release_name(minor_status, src_name);
+           goto enomem;
+       }
+       name->mech = targ_mn;
+       *targ_name = (gss_name_t)name;
+    } else
+       gss_release_name(&junk, &targ_mn);
+
+    return GSS_S_COMPLETE;
+
+enomem:
+    gss_release_name(&junk, &targ_mn);
+    gss_release_name(&junk, &src_mn);
+    *minor_status = ENOMEM;
+    return GSS_S_FAILURE;
 }
 
 OM_uint32 _gss_spnego_wrap_size_limit (
index fbc231f3aebbdb53d73ff8d31a8e55e105f10daf..6c9a03a3b0042c66f7c81115310ebfc353da5089 100644 (file)
@@ -33,7 +33,7 @@
 #include "spnego/spnego_locl.h"
 #include <gssapi_mech.h>
 
-RCSID("$Id: external.c 18336 2006-10-07 22:27:13Z lha $");
+RCSID("$Id: external.c 22600 2008-02-21 12:46:24Z lha $");
 
 /*
  * RFC2478, SPNEGO:
@@ -57,7 +57,7 @@ static gssapi_mech_interface_desc spnego_mech = {
     _gss_spnego_verify_mic,
     _gss_spnego_wrap,
     _gss_spnego_unwrap,
-    _gss_spnego_display_status,
+    NULL,
     NULL,
     _gss_spnego_compare_name,
     _gss_spnego_display_name,
index 7c74981e664e880a9bd6ee45da07d2d947df6978..bee489589810d076fb4047f71ec39621f42ac1e8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "spnego/spnego_locl.h"
 
-RCSID("$Id: init_sec_context.c 19411 2006-12-18 15:42:03Z lha $");
+RCSID("$Id: init_sec_context.c 22600 2008-02-21 12:46:24Z lha $");
 
 /*
  * Is target_name an sane target for `mech´.
@@ -59,8 +59,10 @@ initiator_approved(gss_name_t target_name, gss_OID mech)
                                    &out,
                                    NULL,
                                    NULL);
-    if (GSS_ERROR(maj_stat))
+    if (GSS_ERROR(maj_stat)) {
+       gss_mg_collect_error(mech, maj_stat, min_stat);
        return GSS_S_BAD_MECH;
+    }
     gss_release_buffer(&min_stat, &out);
     gss_delete_sec_context(&min_stat, &ctx, NULL);
 
@@ -268,6 +270,7 @@ spnego_initial
     if (GSS_ERROR(sub)) {
        free_NegTokenInit(&ni);
        *minor_status = minor;
+       gss_mg_collect_error(ctx->preferred_mech_type, sub, minor);
        _gss_spnego_internal_delete_sec_context(&minor, &context, GSS_C_NO_BUFFER);
        return sub;
     }
@@ -480,7 +483,8 @@ spnego_reply
        return GSS_S_BAD_MECH;
     }
 
-    if (resp.responseToken != NULL || 
+    /* if a token (of non zero length), or no context, pass to underlaying mech */
+    if ((resp.responseToken != NULL && resp.responseToken->length) || 
        ctx->negotiated_ctx_id == GSS_C_NO_CONTEXT) {
        gss_buffer_desc mech_input_token;
 
@@ -515,6 +519,7 @@ spnego_reply
        if (GSS_ERROR(ret)) {
            HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
            free_NegTokenResp(&resp);
+           gss_mg_collect_error(&mech, ret, minor);
            *minor_status = minor;
            return ret;
        }
index d80db0018adfc173f3a83dac91b57844f57846b9..69f4d8423d24e63aa911b0689b5b1e73ecc3f275 100644 (file)
@@ -90,15 +90,6 @@ _gss_spnego_display_name (
        gss_buffer_t /*output_name_buffer*/,
        gss_OID * output_name_type );
 
-OM_uint32
-_gss_spnego_display_status (
-       OM_uint32 * /*minor_status*/,
-       OM_uint32 /*status_value*/,
-       int /*status_type*/,
-       const gss_OID /*mech_type*/,
-       OM_uint32 * /*message_context*/,
-       gss_buffer_t status_string );
-
 OM_uint32
 _gss_spnego_duplicate_name (
         OM_uint32 * /*minor_status*/,
index 698da2fe0b1d89b0923ed7a1593ddaa26b05082b..6076478bbb04bdddc9ef612e4bdd0d521924c4a1 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: bn.c 18449 2006-10-14 09:21:09Z lha $");
+RCSID("$Id: bn.c 22261 2007-12-09 06:24:18Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -232,9 +232,9 @@ BN_set_negative(BIGNUM *bn, int flag)
 }
 
 int
-BN_is_negative(BIGNUM *bn)
+BN_is_negative(const BIGNUM *bn)
 {
-    return ((heim_integer *)bn)->negative ? 1 : 0;
+    return ((const heim_integer *)bn)->negative ? 1 : 0;
 }
 
 static const unsigned char is_set[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
index 82c9991c2cb96298545e3ac51d212101d474a7a4..92cacec2a66cec0f27738a78967f50d997a09cb3 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 /*
- * $Id: bn.h 16536 2006-01-13 08:27:50Z lha $
+ * $Id: bn.h 22260 2007-12-09 06:23:47Z lha $
  */
 
 #ifndef _HEIM_BN_H
@@ -97,7 +97,7 @@ int   BN_num_bytes(const BIGNUM *);
 int    BN_cmp(const BIGNUM *, const BIGNUM *);
 
 void   BN_set_negative(BIGNUM *, int);
-int    BN_is_negative(BIGNUM *);
+int    BN_is_negative(const BIGNUM *);
 
 int    BN_is_bit_set(const BIGNUM *, int);
 int    BN_set_bit(BIGNUM *, int);
diff --git a/source/heimdal/lib/hcrypto/camellia-ntt.c b/source/heimdal/lib/hcrypto/camellia-ntt.c
new file mode 100644 (file)
index 0000000..c32c406
--- /dev/null
@@ -0,0 +1,1461 @@
+/* camellia.h  ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * Algorithm Specification 
+ *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "camellia.h"
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ *  macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt)                            \
+    (((u32)(pt)[0] << 24)                      \
+     ^ ((u32)(pt)[1] << 16)                    \
+     ^ ((u32)(pt)[2] <<  8)                    \
+     ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st)  {                     \
+       (ct)[0] = (u8)((st) >> 24);             \
+       (ct)[1] = (u8)((st) >> 16);             \
+       (ct)[2] = (u8)((st) >>  8);             \
+       (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)   \
+    do {                                               \
+       w0 = ll;                                        \
+       ll = (ll << bits) + (lr >> (32 - bits));        \
+       lr = (lr << bits) + (rl >> (32 - bits));        \
+       rl = (rl << bits) + (rr >> (32 - bits));        \
+       rr = (rr << bits) + (w0 >> (32 - bits));        \
+    } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)        \
+    do {                                               \
+       w0 = ll;                                        \
+       w1 = lr;                                        \
+       ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+       lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+       rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+       rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+    } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)     \
+    do {                                                       \
+       il = xl ^ kl;                                           \
+       ir = xr ^ kr;                                           \
+       t0 = il >> 16;                                          \
+       t1 = ir >> 16;                                          \
+       yl = CAMELLIA_SP1110(ir & 0xff)                         \
+           ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP3033(t1 & 0xff)                        \
+           ^ CAMELLIA_SP4404((ir >> 8) & 0xff);                \
+       yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)                  \
+           ^ CAMELLIA_SP0222(t0 & 0xff)                        \
+           ^ CAMELLIA_SP3033((il >> 8) & 0xff)                 \
+           ^ CAMELLIA_SP4404(il & 0xff);                       \
+       yl ^= yr;                                               \
+       yr = CAMELLIA_RR8(yr);                                  \
+       yr ^= yl;                                               \
+    } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+    do {                                                               \
+       t0 = kll;                                                       \
+       t0 &= ll;                                                       \
+       lr ^= CAMELLIA_RL1(t0);                                         \
+       t1 = klr;                                                       \
+       t1 |= lr;                                                       \
+       ll ^= t1;                                                       \
+                                                                       \
+       t2 = krr;                                                       \
+       t2 |= rr;                                                       \
+       rl ^= t2;                                                       \
+       t3 = krl;                                                       \
+       t3 &= rl;                                                       \
+       rr ^= CAMELLIA_RL1(t3);                                         \
+    } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
+    do {                                                               \
+       ir = CAMELLIA_SP1110(xr & 0xff)                                 \
+           ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP4404((xr >> 8) & 0xff);                        \
+       il = CAMELLIA_SP1110((xl >> 24) & 0xff)                         \
+           ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
+           ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
+           ^ CAMELLIA_SP4404(xl & 0xff);                               \
+       il ^= kl;                                                       \
+       ir ^= kr;                                                       \
+       ir ^= il;                                                       \
+       il = CAMELLIA_RR8(il);                                          \
+       il ^= ir;                                                       \
+       yl ^= ir;                                                       \
+       yr ^= il;                                                       \
+    } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+    0xe4e4e400,0x85858500,0x57575700,0x35353500,
+    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+    0x45454500,0x19191900,0xa5a5a500,0x21212100,
+    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+    0x53535300,0x18181800,0xf2f2f200,0x22222200,
+    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+    0xa1a1a100,0x89898900,0x62626200,0x97979700,
+    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+    0x10101000,0xc4c4c400,0x00000000,0x48484800,
+    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+    0xd4d4d400,0x25252500,0xababab00,0x42424200,
+    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+    0x72727200,0x07070700,0xb9b9b900,0x55555500,
+    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+    0x00202020,0x00898989,0x00000000,0x00909090,
+    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+    0x009b9b9b,0x00949494,0x00212121,0x00666666,
+    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+    0x00777777,0x00939393,0x00868686,0x00838383,
+    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+    0x38003838,0x41004141,0x16001616,0x76007676,
+    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+    0x75007575,0x06000606,0x57005757,0xa000a0a0,
+    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+    0x3a003a3a,0x09000909,0x95009595,0x10001010,
+    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+    0x12001212,0x04000404,0x74007474,0x54005454,
+    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+    0x55005555,0x68006868,0x50005050,0xbe00bebe,
+    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+    0x70007070,0xff00ffff,0x32003232,0x69006969,
+    0x08000808,0x62006262,0x00000000,0x24002424,
+    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+    0x45004545,0x81008181,0x73007373,0x6d006d6d,
+    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+    0xe600e6e6,0x25002525,0x48004848,0x99009999,
+    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+    0x7c007c7c,0x77007777,0x56005656,0x05000505,
+    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+    0x24240024,0xe8e800e8,0x60600060,0x69690069,
+    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+    0x10100010,0x00000000,0xa3a300a3,0x75750075,
+    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+    0x81810081,0x6f6f006f,0x13130013,0x63630063,
+    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+    0x78780078,0x06060006,0xe7e700e7,0x71710071,
+    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+    0x15150015,0xadad00ad,0x77770077,0x80800080,
+    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+    0x85850085,0x35350035,0x0c0c000c,0x41410041,
+    0xefef00ef,0x93930093,0x19190019,0x21210021,
+    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+    0x12120012,0x20200020,0xb1b100b1,0x99990099,
+    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+    0x0f0f000f,0x16160016,0x18180018,0x22220022,
+    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+    0x49490049,0x68680068,0x38380038,0xa4a400a4,
+    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+    u32 kll, klr, krl, krr;
+    u32 il, ir, t0, t1, w0, w1;
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[26];
+    u32 subR[26];
+
+    /**
+     *  k == kll || klr || krl || krr (|| is concatination)
+     */
+    kll = GETU32(key     );
+    klr = GETU32(key +  4);
+    krl = GETU32(key +  8);
+    krr = GETU32(key + 12);
+    /**
+     * generate KL dependent subkeys
+     */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(4) = kll; subr(4) = klr;
+    subl(5) = krl; subr(5) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(10) = kll; subr(10) = klr;
+    subl(11) = krl; subr(11) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(18) = kll; subr(18) = klr;
+    subl(19) = krl; subr(19) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+
+    /* generate KA */
+    kll = subl(0); klr = subr(0);
+    krl = subl(1); krr = subr(1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KA dependent subkeys */
+    subl(2) = kll; subr(2) = klr;
+    subl(3) = krl; subr(3) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(8) = kll; subr(8) = klr;
+    subl(9) = krl; subr(9) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(12) = kll; subr(12) = klr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(20) = kll; subr(20) = klr;
+    subl(21) = krl; subr(21) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(24) = kll; subr(24) = klr;
+    subl(25) = krl; subr(25) = krr;
+
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(25); kw4r = subr(25);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16),        tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17),        tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    CamelliaSubkeyL(23) = subl(22);
+    CamelliaSubkeyR(23) = subr(22);
+    CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+    CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+    return;
+}
+
+void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+    u32 kll,klr,krl,krr;           /* left half of key */
+    u32 krll,krlr,krrl,krrr;       /* right half of key */
+    u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
+    u32 kw4l, kw4r, dw, tl, tr;
+    u32 subL[34];
+    u32 subR[34];
+
+    /**
+     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+     *  (|| is concatination)
+     */
+
+    kll  = GETU32(key     );
+    klr  = GETU32(key +  4);
+    krl  = GETU32(key +  8);
+    krr  = GETU32(key + 12);
+    krll = GETU32(key + 16);
+    krlr = GETU32(key + 20);
+    krrl = GETU32(key + 24);
+    krrr = GETU32(key + 28);
+
+    /* generate KL dependent subkeys */
+    subl(0) = kll; subr(0) = klr;
+    subl(1) = krl; subr(1) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+    subl(12) = kll; subr(12) = klr;
+    subl(13) = krl; subr(13) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(16) = kll; subr(16) = klr;
+    subl(17) = krl; subr(17) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+    subl(22) = kll; subr(22) = klr;
+    subl(23) = krl; subr(23) = krr;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+    subl(30) = kll; subr(30) = klr;
+    subl(31) = krl; subr(31) = krr;
+
+    /* generate KR dependent subkeys */
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(4) = krll; subr(4) = krlr;
+    subl(5) = krrl; subr(5) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+    subl(8) = krll; subr(8) = krlr;
+    subl(9) = krrl; subr(9) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(18) = krll; subr(18) = krlr;
+    subl(19) = krrl; subr(19) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+    subl(26) = krll; subr(26) = krlr;
+    subl(27) = krrl; subr(27) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+    /* generate KA */
+    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+              w0, w1, il, ir, t0, t1);
+    krl ^= w0; krr ^= w1;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+              kll, klr, il, ir, t0, t1);
+    kll ^= krll; klr ^= krlr;
+    CAMELLIA_F(kll, klr,
+              CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+              krl, krr, il, ir, t0, t1);
+    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+    CAMELLIA_F(krl, krr,
+              CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+              w0, w1, il, ir, t0, t1);
+    kll ^= w0; klr ^= w1;
+
+    /* generate KB */
+    krll ^= kll; krlr ^= klr;
+    krrl ^= krl; krrr ^= krr;
+    CAMELLIA_F(krll, krlr,
+              CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+              w0, w1, il, ir, t0, t1);
+    krrl ^= w0; krrr ^= w1;
+    CAMELLIA_F(krrl, krrr,
+              CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+              w0, w1, il, ir, t0, t1);
+    krll ^= w0; krlr ^= w1;
+
+    /* generate KA dependent subkeys */
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+    subl(6) = kll; subr(6) = klr;
+    subl(7) = krl; subr(7) = krr;
+    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+    subl(14) = kll; subr(14) = klr;
+    subl(15) = krl; subr(15) = krr;
+    subl(24) = klr; subr(24) = krl;
+    subl(25) = krr; subr(25) = kll;
+    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+    subl(28) = kll; subr(28) = klr;
+    subl(29) = krl; subr(29) = krr;
+
+    /* generate KB dependent subkeys */
+    subl(2) = krll; subr(2) = krlr;
+    subl(3) = krrl; subr(3) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(10) = krll; subr(10) = krlr;
+    subl(11) = krrl; subr(11) = krrr;
+    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+    subl(20) = krll; subr(20) = krlr;
+    subl(21) = krrl; subr(21) = krrr;
+    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+    subl(32) = krll; subr(32) = krlr;
+    subl(33) = krrl; subr(33) = krrr;
+
+    /* absorb kw2 to other subkeys */
+    subl(3) ^= subl(1); subr(3) ^= subr(1);
+    subl(5) ^= subl(1); subr(5) ^= subr(1);
+    subl(7) ^= subl(1); subr(7) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(9);
+    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(11) ^= subl(1); subr(11) ^= subr(1);
+    subl(13) ^= subl(1); subr(13) ^= subr(1);
+    subl(15) ^= subl(1); subr(15) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(17);
+    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(19) ^= subl(1); subr(19) ^= subr(1);
+    subl(21) ^= subl(1); subr(21) ^= subr(1);
+    subl(23) ^= subl(1); subr(23) ^= subr(1);
+    subl(1) ^= subr(1) & ~subr(25);
+    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+    subl(27) ^= subl(1); subr(27) ^= subr(1);
+    subl(29) ^= subl(1); subr(29) ^= subr(1);
+    subl(31) ^= subl(1); subr(31) ^= subr(1);
+    subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+    /* absorb kw4 to other subkeys */
+    kw4l = subl(33); kw4r = subr(33);
+    subl(30) ^= kw4l; subr(30) ^= kw4r;
+    subl(28) ^= kw4l; subr(28) ^= kw4r;
+    subl(26) ^= kw4l; subr(26) ^= kw4r;
+    kw4l ^= kw4r & ~subr(24);
+    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+    subl(22) ^= kw4l; subr(22) ^= kw4r;
+    subl(20) ^= kw4l; subr(20) ^= kw4r;
+    subl(18) ^= kw4l; subr(18) ^= kw4r;
+    kw4l ^= kw4r & ~subr(16);
+    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+    subl(14) ^= kw4l; subr(14) ^= kw4r;
+    subl(12) ^= kw4l; subr(12) ^= kw4r;
+    subl(10) ^= kw4l; subr(10) ^= kw4r;
+    kw4l ^= kw4r & ~subr(8);
+    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+    subl(6) ^= kw4l; subr(6) ^= kw4r;
+    subl(4) ^= kw4l; subr(4) ^= kw4r;
+    subl(2) ^= kw4l; subr(2) ^= kw4r;
+    subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+    /* key XOR is end of F-function */
+    CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+    CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+    CamelliaSubkeyL(2) = subl(3);
+    CamelliaSubkeyR(2) = subr(3);
+    CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+    CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+    CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+    CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+    CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+    CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+    CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+    CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+    tl = subl(10) ^ (subr(10) & ~subr(8));
+    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(7) = subl(6) ^ tl;
+    CamelliaSubkeyR(7) = subr(6) ^ tr;
+    CamelliaSubkeyL(8) = subl(8);
+    CamelliaSubkeyR(8) = subr(8);
+    CamelliaSubkeyL(9) = subl(9);
+    CamelliaSubkeyR(9) = subr(9);
+    tl = subl(7) ^ (subr(7) & ~subr(9));
+    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(10) = tl ^ subl(11);
+    CamelliaSubkeyR(10) = tr ^ subr(11);
+    CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+    CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+    CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+    CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+    CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+    CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+    CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+    CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+    tl = subl(18) ^ (subr(18) & ~subr(16));
+    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(15) = subl(14) ^ tl;
+    CamelliaSubkeyR(15) = subr(14) ^ tr;
+    CamelliaSubkeyL(16) = subl(16);
+    CamelliaSubkeyR(16) = subr(16);
+    CamelliaSubkeyL(17) = subl(17);
+    CamelliaSubkeyR(17) = subr(17);
+    tl = subl(15) ^ (subr(15) & ~subr(17));
+    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(18) = tl ^ subl(19);
+    CamelliaSubkeyR(18) = tr ^ subr(19);
+    CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+    CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+    CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+    CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+    CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+    CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+    CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+    CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+    tl = subl(26) ^ (subr(26) & ~subr(24));
+    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(23) = subl(22) ^ tl;
+    CamelliaSubkeyR(23) = subr(22) ^ tr;
+    CamelliaSubkeyL(24) = subl(24);
+    CamelliaSubkeyR(24) = subr(24);
+    CamelliaSubkeyL(25) = subl(25);
+    CamelliaSubkeyR(25) = subr(25);
+    tl = subl(23) ^ (subr(23) &  ~subr(25));
+    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+    CamelliaSubkeyL(26) = tl ^ subl(27);
+    CamelliaSubkeyR(26) = tr ^ subr(27);
+    CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+    CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+    CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+    CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+    CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+    CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+    CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+    CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+    CamelliaSubkeyL(31) = subl(30);
+    CamelliaSubkeyR(31) = subr(30);
+    CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+    CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+    /* apply the inverse of the last half of P-function */
+    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+    
+    return;
+}
+
+void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+    unsigned char kk[32];
+    u32 krll, krlr, krrl,krrr;
+
+    memcpy(kk, key, 24);
+    memcpy((unsigned char *)&krll, key+16,4);
+    memcpy((unsigned char *)&krlr, key+20,4);
+    krrl = ~krll;
+    krrr = ~krlr;
+    memcpy(kk+24, (unsigned char *)&krrl, 4);
+    memcpy(kk+28, (unsigned char *)&krrr, 4);
+    camellia_setup256(kk, subkey);
+    return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il, ir, t0, t1;
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+    /* main iteration */
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(24);
+    io[3] ^= CamelliaSubkeyR(24);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+       
+    return;
+}
+
+void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;               /* temporary valiables */
+    
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(24);
+    io[1] ^= CamelliaSubkeyR(24);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(0);
+    io[1] ^= CamelliaSubkeyR(0);
+
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(32);
+    io[3] ^= CamelliaSubkeyR(32);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+    u32 il,ir,t0,t1;           /* temporary valiables */
+
+    /* pre whitening but absorb kw2*/
+    io[0] ^= CamelliaSubkeyL(32);
+    io[1] ^= CamelliaSubkeyR(32);
+       
+    /* main iteration */
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+                CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+                CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+                    io[0],io[1],il,ir,t0,t1);
+
+    CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+                CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+                CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+                t0,t1,il,ir);
+
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+                    io[0],io[1],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[0],io[1],
+                    CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+                    io[2],io[3],il,ir,t0,t1);
+    CAMELLIA_ROUNDSM(io[2],io[3],
+                    CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+                    io[0],io[1],il,ir,t0,t1);
+
+    /* post whitening but kw4 */
+    io[2] ^= CamelliaSubkeyL(0);
+    io[3] ^= CamelliaSubkeyR(0);
+
+    t0 = io[0];
+    t1 = io[1];
+    io[0] = io[2];
+    io[1] = io[3];
+    io[2] = t0;
+    io[3] = t1;
+
+    return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength, 
+                     const unsigned char *rawKey, 
+                     KEY_TABLE_TYPE keyTable)
+{
+    switch(keyBitLength) {
+    case 128:
+       camellia_setup128(rawKey, keyTable);
+       break;
+    case 192:
+       camellia_setup192(rawKey, keyTable);
+       break;
+    case 256:
+       camellia_setup256(rawKey, keyTable);
+       break;
+    default:
+       break;
+    }
+}
+
+
+void Camellia_EncryptBlock(const int keyBitLength, 
+                          const unsigned char *plaintext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *ciphertext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(plaintext);
+    tmp[1] = GETU32(plaintext + 4);
+    tmp[2] = GETU32(plaintext + 8);
+    tmp[3] = GETU32(plaintext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_encrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_encrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+
+    PUTU32(ciphertext, tmp[0]);
+    PUTU32(ciphertext + 4, tmp[1]);
+    PUTU32(ciphertext + 8, tmp[2]);
+    PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength, 
+                          const unsigned char *ciphertext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *plaintext)
+{
+    u32 tmp[4];
+
+    tmp[0] = GETU32(ciphertext);
+    tmp[1] = GETU32(ciphertext + 4);
+    tmp[2] = GETU32(ciphertext + 8);
+    tmp[3] = GETU32(ciphertext + 12);
+
+    switch (keyBitLength) {
+    case 128:
+       camellia_decrypt128(keyTable, tmp);
+       break;
+    case 192:
+       /* fall through */
+    case 256:
+       camellia_decrypt256(keyTable, tmp);
+       break;
+    default:
+       break;
+    }
+    PUTU32(plaintext, tmp[0]);
+    PUTU32(plaintext + 4, tmp[1]);
+    PUTU32(plaintext + 8, tmp[2]);
+    PUTU32(plaintext + 12, tmp[3]);
+}
diff --git a/source/heimdal/lib/hcrypto/camellia-ntt.h b/source/heimdal/lib/hcrypto/camellia-ntt.h
new file mode 100644 (file)
index 0000000..740ed8b
--- /dev/null
@@ -0,0 +1,54 @@
+/* camellia.h  ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+                     const unsigned char *rawKey, 
+                     KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+                          const unsigned char *plaintext, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength, 
+                          const unsigned char *cipherText, 
+                          const KEY_TABLE_TYPE keyTable, 
+                          unsigned char *plaintext);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
diff --git a/source/heimdal/lib/hcrypto/camellia.c b/source/heimdal/lib/hcrypto/camellia.c
new file mode 100644 (file)
index 0000000..2047b75
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+
+RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $");
+#endif
+
+#ifdef KRB5
+#include <krb5-types.h>
+#endif
+
+#include <string.h>
+
+#include "camellia-ntt.h"
+#include "camellia.h"
+
+int
+CAMELLIA_set_key(const unsigned char *userkey, 
+                const int bits, CAMELLIA_KEY *key)
+{
+    key->bits = bits;
+    Camellia_Ekeygen(bits, userkey, key->key);
+    return 1;
+}
+
+void
+CAMELLIA_encrypt(const unsigned char *in, unsigned char *out, 
+                const CAMELLIA_KEY *key)
+{
+    Camellia_EncryptBlock(key->bits, in, key->key, out);
+
+}
+
+void
+CAMELLIA_decrypt(const unsigned char *in, unsigned char *out, 
+                const CAMELLIA_KEY *key)
+{
+    Camellia_DecryptBlock(key->bits, in, key->key, out);
+}
+
+void
+CAMELLIA_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                    unsigned long size, const CAMELLIA_KEY *key,
+                    unsigned char *iv, int mode_encrypt)
+{
+    unsigned char tmp[CAMELLIA_BLOCK_SIZE];
+    int i;
+
+    if (mode_encrypt) {
+       while (size >= CAMELLIA_BLOCK_SIZE) {
+           for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+               tmp[i] = in[i] ^ iv[i];
+           CAMELLIA_encrypt(tmp, out, key);
+           memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+           size -= CAMELLIA_BLOCK_SIZE;
+           in += CAMELLIA_BLOCK_SIZE;
+           out += CAMELLIA_BLOCK_SIZE;
+       }
+       if (size) {
+           for (i = 0; i < size; i++)
+               tmp[i] = in[i] ^ iv[i];
+           for (i = size; i < CAMELLIA_BLOCK_SIZE; i++)
+               tmp[i] = iv[i];
+           CAMELLIA_encrypt(tmp, out, key);
+           memcpy(iv, out, CAMELLIA_BLOCK_SIZE);
+       }
+    } else {
+       while (size >= CAMELLIA_BLOCK_SIZE) {
+           memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+           CAMELLIA_decrypt(tmp, out, key);
+           for (i = 0; i < CAMELLIA_BLOCK_SIZE; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+           size -= CAMELLIA_BLOCK_SIZE;
+           in += CAMELLIA_BLOCK_SIZE;
+           out += CAMELLIA_BLOCK_SIZE;
+       }
+       if (size) {
+           memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
+           CAMELLIA_decrypt(tmp, out, key);
+           for (i = 0; i < size; i++)
+               out[i] ^= iv[i];
+           memcpy(iv, tmp, CAMELLIA_BLOCK_SIZE);
+       }
+    }
+}
diff --git a/source/heimdal/lib/hcrypto/camellia.h b/source/heimdal/lib/hcrypto/camellia.h
new file mode 100644 (file)
index 0000000..3b21934
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_CAMELLIA_H
+#define HEIM_CAMELLIA_H 1
+
+#include <krb5-types.h>
+#include "camellia-ntt.h"
+
+/* symbol renaming */
+#define CAMELLIA_set_key hc_CAMELLIA_set_encrypt_key
+#define CAMELLIA_encrypt hc_CAMELLIA_encrypt
+#define CAMELLIA_decrypt hc_CAMELLIA_decrypt
+#define CAMELLIA_cbc_encrypt hc_CAMELLIA_cbc_encrypt
+
+/*
+ *
+ */
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_MAXNR 14
+
+#define CAMELLIA_ENCRYPT 1
+#define CAMELLIA_DECRYPT 0
+
+typedef struct camellia_key {
+    unsigned int bits;
+    KEY_TABLE_TYPE key;
+} CAMELLIA_KEY;
+
+int CAMELLIA_set_key(const unsigned char *, const int, CAMELLIA_KEY *);
+
+void CAMELLIA_encrypt(const unsigned char *, unsigned char *,
+                     const CAMELLIA_KEY *);
+void CAMELLIA_decrypt(const unsigned char *, unsigned char *,
+                     const CAMELLIA_KEY *);
+
+void CAMELLIA_cbc_encrypt(const unsigned char *, unsigned char *,
+                         const unsigned long, const CAMELLIA_KEY *,
+                         unsigned char *, int);
+
+#endif /* HEIM_CAMELLIA_H */
index 17592bbdf69d4474087c19c90b7be093d240c3aa..494d436d131118f00a0ca733d13e8e9bd9ff8c16 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "imath/imath.h"
 
-RCSID("$Id: dh-imath.c 18645 2006-10-20 06:56:57Z lha $");
+RCSID("$Id: dh-imath.c 22368 2007-12-28 15:27:52Z lha $");
 
 static void
 BN2mpz(mpz_t *s, const BIGNUM *bn)
@@ -224,7 +224,7 @@ dh_finish(DH *dh)
  *
  */
 
-const DH_METHOD hc_dh_imath_method = {
+const DH_METHOD _hc_dh_imath_method = {
     "hcrypto imath DH",
     dh_generate_key,
     dh_compute_key,
@@ -236,8 +236,16 @@ const DH_METHOD hc_dh_imath_method = {
     dh_generate_params
 };
 
+/**
+ * DH implementation using libimath.
+ *
+ * @return the DH_METHOD for the DH implementation using libimath.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 const DH_METHOD *
 DH_imath_method(void)
 {
-    return &hc_dh_imath_method;
+    return &_hc_dh_imath_method;
 }
index b558eb901cce84b9d0eabf1eddfe6e42f91cf772..9f1af0b3b114b8fabd7a3c29ffb90bd49eb1b6e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: dh.c 18618 2006-10-19 17:31:51Z lha $");
+RCSID("$Id: dh.c 22397 2008-01-01 20:20:31Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,8 +43,23 @@ RCSID("$Id: dh.c 18618 2006-10-19 17:31:51Z lha $");
 
 #include <roken.h>
 
-/*
+/**
+ * @page page_dh DH - Diffie-Hellman key exchange
+ *
+ * Diffie-Hellman key exchange is a protocol that allows two parties
+ * to establish a shared secret key.
+ *
+ * Include and example how to use DH_new() and friends here.
  *
+ * See the library functions here: @ref hcrypto_dh
+ */
+
+/**
+ * Create a new DH object using DH_new_method(NULL), see DH_new_method().
+ *
+ * @return a newly allocated DH object.
+ *
+ * @ingroup hcrypto_dh
  */
 
 DH *
@@ -53,6 +68,17 @@ DH_new(void)
     return DH_new_method(NULL);
 }
 
+/**
+ * Create a new DH object from the given engine, if the NULL is used,
+ * the default engine is used. Free the DH object with DH_free().
+ *
+ * @param engine The engine to use to allocate the DH object. 
+ *
+ * @return a newly allocated DH object.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 DH *
 DH_new_method(ENGINE *engine)
 {
@@ -88,6 +114,15 @@ DH_new_method(ENGINE *engine)
     return dh;
 }
 
+/**
+ * Free a DH object and release related resources, like ENGINE, that
+ * the object was using.
+ *
+ * @param dh object to be freed.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 void
 DH_free(DH *dh)
 {
@@ -116,18 +151,52 @@ DH_free(DH *dh)
     free(dh);
 }    
 
+/**
+ * Add a reference to the DH object. The object should be free with
+ * DH_free() to drop the reference.
+ *
+ * @param dh the object to increase the reference count too.
+ *
+ * @return the updated reference count, can't safely be used except
+ * for debug printing.
+ * 
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_up_ref(DH *dh)
 {
     return ++dh->references;
 }
 
+/**
+ * The maximum output size of the DH_compute_key() function.
+ *
+ * @param dh The DH object to get the size from.
+ *
+ * @return the maximum size in bytes of the out data.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_size(const DH *dh)
 {
     return BN_num_bytes(dh->p);
 }
 
+/**
+ * Set the data index idx in the DH object to data.
+ *
+ * @param dh DH object.
+ * @param idx index to set the data for.
+ * @param data data to store for the index idx.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_set_ex_data(DH *dh, int idx, void *data)
 {
@@ -135,12 +204,36 @@ DH_set_ex_data(DH *dh, int idx, void *data)
     return 1;
 }
 
+/**
+ * Get the data for index idx in the DH object.
+ *
+ * @param dh DH object.
+ * @param idx index to get the data for.
+ *
+ * @return the object store in index idx
+ *
+ * @ingroup hcrypto_dh
+ */
+
 void *
 DH_get_ex_data(DH *dh, int idx)
 {
     return dh->ex_data.sk;
 }
 
+/**
+ * Generate DH parameters for the DH object give parameters.
+ *
+ * @param dh The DH object to generate parameters for.
+ * @param prime_len length of the prime
+ * @param generator generator, g
+ * @param cb Callback parameters to show progress, can be NULL.
+ *
+ * @return the maximum size in bytes of the out data.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb)
 {
@@ -149,12 +242,17 @@ DH_generate_parameters_ex(DH *dh, int prime_len, int generator, BN_GENCB *cb)
     return 0;
 }
 
-/*
- * Check that
+/**
+ * Check that the public key is sane.
  *
- *     pub_key > 1    and    pub_key < p - 1
+ * @param dh the local peer DH parameters.
+ * @param pub_key the remote peer public key parameters.
+ * @param codes return that the failures of the pub_key are.
  *
- * to avoid small subgroups attack.
+ * @return 1 on success, 0 on failure and *codes is set the the
+ * combined fail check for the public key
+ *
+ * @ingroup hcrypto_dh
  */
 
 int
@@ -165,6 +263,19 @@ DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
 
     *codes = 0;
 
+    /**
+     * Checks that the function performs are:
+     * - pub_key is not negative 
+     */
+
+    if (BN_is_negative(pub_key))
+       goto out;
+
+    /**
+     * - pub_key > 1    and    pub_key < p - 1,
+     *    to avoid small subgroups attack.
+     */
+
     bn = BN_new();
     if (bn == NULL)
        goto out;
@@ -184,6 +295,28 @@ DH_check_pubkey(const DH *dh, const BIGNUM *pub_key, int *codes)
     if (BN_cmp(sum, dh->p) >= 0)
        *codes |= DH_CHECK_PUBKEY_TOO_LARGE;
 
+    /**
+     * - if g == 2, pub_key have more then one bit set,
+     *   if bits set is 1, log_2(pub_key) is trival
+     */
+
+    if (!BN_set_word(bn, 2))
+       goto out;
+
+    if (BN_cmp(bn, pub_key) == 0) {
+       unsigned i, n = BN_num_bits(pub_key);
+       unsigned bits = 0;
+
+       for (i = 0; i <= n; i++)
+           if (BN_is_bit_set(pub_key, i))
+               bits++;
+
+       if (bits > 1) {
+           *codes |= DH_CHECK_PUBKEY_TOO_SMALL;
+           goto out;
+       }
+    }
+
     ret = 1;
 out:
     if (bn)
@@ -194,24 +327,64 @@ out:
     return ret;
 }
 
+/**
+ * Generate a new DH private-public key pair. The dh parameter must be
+ * allocted first with DH_new(). dh->p and dp->g must be set.
+ *
+ * @param dh dh parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_generate_key(DH *dh)
 {
     return dh->meth->generate_key(dh);
 }
 
+/**
+ * Complute the shared secret key.
+ *
+ * @param shared_key the resulting shared key, need to be at least
+ * DH_size() large.
+ * @param peer_pub_key the peer's public key.
+ * @param dh the dh key pair.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_compute_key(unsigned char *shared_key,
               const BIGNUM *peer_pub_key, DH *dh)
 {
     int codes;
 
+    /**
+     * Checks that the pubkey passed in is valid using
+     * DH_check_pubkey().
+     */
+
     if (!DH_check_pubkey(dh, peer_pub_key, &codes) || codes != 0)
        return -1;
 
     return dh->meth->compute_key(shared_key, peer_pub_key, dh);
 }
 
+/**
+ * Set a new method for the DH keypair.
+ *
+ * @param dh dh parameter.
+ * @param method the new method for the DH parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 int
 DH_set_method(DH *dh, const DH_METHOD *method)
 {
@@ -271,8 +444,16 @@ static const DH_METHOD dh_null_method = {
     dh_null_generate_params
 };
 
-extern const DH_METHOD hc_dh_imath_method;
-static const DH_METHOD *dh_default_method = &hc_dh_imath_method;
+extern const DH_METHOD _hc_dh_imath_method;
+static const DH_METHOD *dh_default_method = &_hc_dh_imath_method;
+
+/**
+ * Return the dummy DH implementation.
+ *
+ * @return pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
 
 const DH_METHOD *
 DH_null_method(void)
@@ -280,12 +461,28 @@ DH_null_method(void)
     return &dh_null_method;
 }
 
+/**
+ * Set the default DH implementation.
+ *
+ * @param meth pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 void
 DH_set_default_method(const DH_METHOD *meth)
 {
     dh_default_method = meth;
 }
 
+/**
+ * Return the default DH implementation.
+ *
+ * @return pointer to a DH_METHOD.
+ *
+ * @ingroup hcrypto_dh
+ */
+
 const DH_METHOD *
 DH_get_default_method(void)
 {
index 19b0ac85e7a0250341b3121254e8a46f70eb2157..788000b05489e2fecc7b82ce03acb914103c3963 100644 (file)
@@ -1,7 +1,42 @@
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
+RCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $");
+
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -13,6 +48,7 @@
 #include <krb5-types.h>
 
 #include <aes.h>
+#include "camellia.h"
 #include <des.h>
 #include <sha.h>
 #include <rc2.h>
 #include <md4.h>
 #include <md5.h>
 
+/**
+ * @page page_evp EVP - generic crypto interface
+ *
+ * See the library functions here: @ref hcrypto_evp
+ */
+
+
 typedef int (*evp_md_init)(EVP_MD_CTX *);
 typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t);
 typedef int (*evp_md_final)(void *, EVP_MD_CTX *);
@@ -36,8 +79,14 @@ struct hc_evp_md {
     evp_md_cleanup cleanup;
 };
 
-/*
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param md the evp message
  *
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
  */
 
 size_t
@@ -46,24 +95,60 @@ EVP_MD_size(const EVP_MD *md)
     return md->hash_size;
 }
 
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param md the evp message
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_MD_block_size(const EVP_MD *md)
 {
     return md->block_size;
 }
 
+/**
+ * Allocate a messsage digest context object. Free with
+ * EVP_MD_CTX_destroy().
+ *
+ * @return a newly allocated message digest context object.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 EVP_MD_CTX *
 EVP_MD_CTX_create(void)
 {
     return calloc(1, sizeof(EVP_MD_CTX));
 }
 
+/**
+ * Initiate a messsage digest context object. Deallocate with
+ * EVP_MD_CTX_cleanup(). Please use EVP_MD_CTX_create() instead.
+ *
+ * @param ctx variable to initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 void
 EVP_MD_CTX_init(EVP_MD_CTX *ctx)
 {
     memset(ctx, 0, sizeof(*ctx));
 }
 
+/**
+ * Free a messsage digest context object.
+ *
+ * @param ctx context to free.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 void
 EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
 {
@@ -71,6 +156,16 @@ EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
     free(ctx);
 }
 
+/**
+ * Free the resources used by the EVP_MD context.
+ *
+ * @param ctx the context to free the resources from.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
 {
@@ -79,9 +174,19 @@ EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
     ctx->md = NULL;
     ctx->engine = NULL;
     free(ctx->ptr);
+    memset(ctx, 0, sizeof(*ctx));
     return 1;
 }
 
+/**
+ * Get the EVP_MD use for a specified context.
+ *
+ * @param ctx the EVP_MD context to get the EVP_MD for.
+ *
+ * @return the EVP_MD used for the context.
+ *
+ * @ingroup hcrypto_evp
+ */
 
 const EVP_MD *
 EVP_MD_CTX_md(EVP_MD_CTX *ctx)
@@ -89,18 +194,50 @@ EVP_MD_CTX_md(EVP_MD_CTX *ctx)
     return ctx->md;
 }
 
+/**
+ * Return the output size of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size output size of the message digest function.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_MD_CTX_size(EVP_MD_CTX *ctx)
 {
     return EVP_MD_size(ctx->md);
 }
 
+/**
+ * Return the blocksize of the message digest function.
+ *
+ * @param ctx the evp message digest context
+ *
+ * @return size size of the message digest block size
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_MD_CTX_block_size(EVP_MD_CTX *ctx)
 {
     return EVP_MD_block_size(ctx->md);
 }
 
+/**
+ * Init a EVP_MD_CTX for use a specific message digest and engine.
+ *
+ * @param ctx the message digest context to init.
+ * @param md the message digest to use.
+ * @param engine the engine to use, NULL to use the default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
 {
@@ -117,6 +254,18 @@ EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
     return 1;
 }
 
+/**
+ * Update the digest with some data.
+ *
+ * @param ctx the context to update
+ * @param data the data to update the context with
+ * @param size length of data
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
 {
@@ -124,6 +273,19 @@ EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
     return 1;
 }
 
+/**
+ * Complete the message digest.
+ *
+ * @param ctx the context to complete.
+ * @param hash the output of the message digest function. At least
+ * EVP_MD_size().
+ * @param size the output size of hash.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
 {
@@ -133,6 +295,23 @@ EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
     return 1;
 }
 
+/**
+ * Do the whole EVP_MD_CTX_create(), EVP_DigestInit_ex(),
+ * EVP_DigestUpdate(), EVP_DigestFinal_ex(), EVP_MD_CTX_destroy()
+ * dance in one call.
+ *
+ * @param data the data to update the context with
+ * @param dsize length of data
+ * @param hash output data of at least EVP_MD_size() length.
+ * @param hsize output length of hash.
+ * @param md message digest to use
+ * @param engine engine to use, NULL for default engine.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize, 
           const EVP_MD *md, ENGINE *engine)
@@ -144,20 +323,26 @@ EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
     if (ctx == NULL)
        return 0;
     ret = EVP_DigestInit_ex(ctx, md, engine);
-    if (ret != 1)
+    if (ret != 1) {
+       EVP_MD_CTX_destroy(ctx);
        return ret;
+    }
     ret = EVP_DigestUpdate(ctx, data, dsize);
-    if (ret != 1)
+    if (ret != 1) {
+       EVP_MD_CTX_destroy(ctx);
        return ret;
+    }
     ret = EVP_DigestFinal_ex(ctx, hash, hsize);
-    if (ret != 1)
-       return ret;
     EVP_MD_CTX_destroy(ctx);
-    return 1;
+    return ret;
 }
 
-/*
+/**
+ * The message digest SHA256
+ *
+ * @return the message digest type.
  *
+ * @ingroup hcrypto_evp
  */
 
 const EVP_MD *
@@ -185,18 +370,42 @@ static const struct hc_evp_md sha1 = {
     NULL
 };
 
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_sha1(void)
 {
     return &sha1;
 }
 
+/**
+ * The message digest SHA1
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_sha(void)
 {
     return &sha1;
 }
 
+/**
+ * The message digest MD5
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_md5(void)
 {
@@ -212,6 +421,14 @@ EVP_md5(void)
     return &md5;
 }
 
+/**
+ * The message digest MD4
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_md4(void)
 {
@@ -227,6 +444,14 @@ EVP_md4(void)
     return &md4;
 }
 
+/**
+ * The message digest MD2
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_md2(void)
 {
@@ -255,10 +480,18 @@ null_Update (void *m, const void * data, size_t size)
 {
 }
 static void
-null_Final(void *res, struct md5 *m)
+null_Final(void *res, void *m)
 {
 }
 
+/**
+ * The null message digest
+ *
+ * @return the message digest type.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_MD *
 EVP_md_null(void)
 {
@@ -282,8 +515,14 @@ int        EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);
 int    EVP_VerifyFinal(EVP_MD_CTX *, const void *, size_t, EVP_PKEY *);
 #endif
 
-/*
+/**
+ * Return the block size of the cipher.
+ *
+ * @param c cipher to get the block size from.
  *
+ * @return the block size of the cipher.
+ *
+ * @ingroup hcrypto_evp
  */
 
 size_t
@@ -292,24 +531,63 @@ EVP_CIPHER_block_size(const EVP_CIPHER *c)
     return c->block_size;
 }
 
+/**
+ * Return the key size of the cipher.
+ *
+ * @param c cipher to get the key size from.
+ *
+ * @return the key size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_CIPHER_key_length(const EVP_CIPHER *c)
 {
     return c->key_len;
 }
 
+/**
+ * Return the IV size of the cipher.
+ *
+ * @param c cipher to get the IV size from.
+ *
+ * @return the IV size of the cipher.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_CIPHER_iv_length(const EVP_CIPHER *c)
 {
     return c->iv_len;
 }
 
+/**
+ * Initiate a EVP_CIPHER_CTX context. Clean up with
+ * EVP_CIPHER_CTX_cleanup().
+ *
+ * @param c the cipher initiate.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 void
 EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
 {
     memset(c, 0, sizeof(*c));
 }
 
+/**
+ * Clean up the EVP_CIPHER_CTX context.
+ *
+ * @param c the cipher to clean up.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
 {
@@ -336,54 +614,149 @@ EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
 }
 #endif
 
+/**
+ * Return the EVP_CIPHER for a EVP_CIPHER_CTX context.
+ *
+ * @param ctx the context to get the cipher type from.
+ *
+ * @return the EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx)
 {
     return ctx->cipher;
 }
 
+/**
+ * Return the block size of the cipher context.
+ *
+ * @param ctx cipher context to get the block size from.
+ *
+ * @return the block size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
 {
     return EVP_CIPHER_block_size(ctx->cipher);
 }
 
+/**
+ * Return the key size of the cipher context.
+ *
+ * @param ctx cipher context to get the key size from.
+ *
+ * @return the key size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
 {
     return EVP_CIPHER_key_length(ctx->cipher);
 }
 
+/**
+ * Return the IV size of the cipher context.
+ *
+ * @param ctx cipher context to get the IV size from.
+ *
+ * @return the IV size of the cipher context.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 size_t
 EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
 {
     return EVP_CIPHER_iv_length(ctx->cipher);
 }
 
+/**
+ * Get the flags for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the flags from
+ *
+ * @return the flags for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 unsigned long
 EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
 {
     return ctx->cipher->flags;
 }
 
+/**
+ * Get the mode for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the mode from
+ *
+ * @return the mode for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx)
 {
     return EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_MODE;
 }
 
+/**
+ * Get the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to get the app data from
+ *
+ * @return the app data for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 void *
 EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *ctx)
 {
     return ctx->app_data;
 }
 
+/**
+ * Set the app data for an EVP_CIPHER_CTX context.
+ *
+ * @param ctx the EVP_CIPHER_CTX to set the app data for
+ * @param data the app data to set for an EVP_CIPHER_CTX.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 void
 EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
 {
     ctx->app_data = data;
 }
 
+/**
+ * Initiate the EVP_CIPHER_CTX context to encrypt or decrypt data.
+ * Clean up with EVP_CIPHER_CTX_cleanup().
+ *
+ * @param ctx context to initiate
+ * @param c cipher to use.
+ * @param engine crypto engine to use, NULL to select default.
+ * @param key the crypto key to use, NULL will use the previous value.
+ * @param iv the IV to use, NULL will use the previous value.
+ * @param encp non zero will encrypt, -1 use the previous value.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
                  const void *key, const void *iv, int encp)
@@ -426,6 +799,17 @@ EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
     return 1;
 }
 
+/**
+ * Encypher/decypher data
+ *
+ * @param ctx the cipher context.
+ * @param out out data from the operation.
+ * @param in in data to the operation.
+ * @param size length of data.
+ *
+ * @return 1 on success.
+ */
+
 int
 EVP_Cipher(EVP_CIPHER_CTX *ctx, void *out, const void *in,size_t size)
 {
@@ -461,6 +845,14 @@ enc_null_cleanup(EVP_CIPHER_CTX *ctx)
     return 1;
 }
 
+/**
+ * The NULL cipher type, does no encryption/decryption.
+ *
+ * @return the null EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_enc_null(void)
 {
@@ -524,6 +916,13 @@ rc2_cleanup(EVP_CIPHER_CTX *ctx)
     return 1;
 }
 
+/**
+ * The RC2 cipher type
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
 
 const EVP_CIPHER *
 EVP_rc2_cbc(void)
@@ -546,6 +945,14 @@ EVP_rc2_cbc(void)
     return &rc2_cbc;
 }
 
+/**
+ * The RC2-40 cipher type
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_rc2_40_cbc(void)
 {
@@ -567,6 +974,14 @@ EVP_rc2_40_cbc(void)
     return &rc2_40_cbc;
 }
 
+/**
+ * The RC2-64 cipher type
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_rc2_64_cbc(void)
 {
@@ -588,8 +1003,12 @@ EVP_rc2_64_cbc(void)
     return &rc2_64_cbc;
 }
 
-/*
+/**
+ * The RC4 cipher type
  *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
  */
 
 const EVP_CIPHER *
@@ -600,6 +1019,14 @@ EVP_rc4(void)
     return NULL;
 }
 
+/**
+ * The RC4-40 cipher type
+ *
+ * @return the RC4-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_rc4_40(void)
 {
@@ -651,6 +1078,14 @@ des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
     return 1;
 }
 
+/**
+ * The tripple DES cipher type
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_des_ede3_cbc(void)
 {
@@ -708,6 +1143,14 @@ aes_cleanup(EVP_CIPHER_CTX *ctx)
     return 1;
 }
 
+/**
+ * The AES-128 cipher type
+ *
+ * @return the AES-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_aes_128_cbc(void)
 {
@@ -729,6 +1172,14 @@ EVP_aes_128_cbc(void)
     return &aes_128_cbc;
 }
 
+/**
+ * The AES-192 cipher type
+ *
+ * @return the AES-192 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 const EVP_CIPHER *
 EVP_aes_192_cbc(void)
 {
@@ -750,6 +1201,13 @@ EVP_aes_192_cbc(void)
     return &aes_192_cbc;
 }
 
+/**
+ * The AES-256 cipher type
+ *
+ * @return the AES-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
 
 const EVP_CIPHER *
 EVP_aes_256_cbc(void)
@@ -772,6 +1230,123 @@ EVP_aes_256_cbc(void)
     return &aes_256_cbc;
 }
 
+static int
+camellia_init(EVP_CIPHER_CTX *ctx,
+        const unsigned char * key,
+        const unsigned char * iv,
+        int encp)
+{
+    CAMELLIA_KEY *k = ctx->cipher_data;
+    k->bits = ctx->cipher->key_len * 8;
+    CAMELLIA_set_key(key, ctx->cipher->key_len * 8, k);
+    return 1;
+}
+
+static int
+camellia_do_cipher(EVP_CIPHER_CTX *ctx,
+             unsigned char *out,
+             const unsigned char *in,
+             unsigned int size)
+{
+    CAMELLIA_KEY *k = ctx->cipher_data;
+    CAMELLIA_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
+    return 1;
+}
+
+static int
+camellia_cleanup(EVP_CIPHER_CTX *ctx)
+{
+    memset(ctx->cipher_data, 0, sizeof(CAMELLIA_KEY));
+    return 1;
+}
+
+/**
+ * The Camellia-128 cipher type
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_128_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       16,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       camellia_cleanup,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
+/**
+ * The Camellia-198 cipher type
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_192_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       24,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       camellia_cleanup,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
+/**
+ * The Camellia-256 cipher type
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+
+const EVP_CIPHER *
+EVP_camellia_256_cbc(void)
+{
+    static const EVP_CIPHER cipher = {
+       0,
+       16,
+       32,
+       16,
+       EVP_CIPH_CBC_MODE,
+       camellia_init,
+       camellia_do_cipher,
+       camellia_cleanup,
+       sizeof(CAMELLIA_KEY),
+       NULL,
+       NULL,
+       NULL,
+       NULL
+    };
+    return &cipher;
+}
+
 /*
  *
  */
@@ -783,9 +1358,21 @@ static const struct cipher_name {
     { "des-ede3-cbc", EVP_des_ede3_cbc },
     { "aes-128-cbc", EVP_aes_128_cbc },
     { "aes-192-cbc", EVP_aes_192_cbc },
-    { "aes-256-cbc", EVP_aes_256_cbc }
+    { "aes-256-cbc", EVP_aes_256_cbc },
+    { "camellia-128-cbc", EVP_camellia_128_cbc },
+    { "camellia-192-cbc", EVP_camellia_192_cbc },
+    { "camellia-256-cbc", EVP_camellia_256_cbc }
 };
 
+/**
+ * Get the cipher type using their name.
+ *
+ * @param name the name of the cipher.
+ *
+ * @return the selected EVP_CIPHER pointer or NULL if not found.
+ *
+ * @ingroup hcrypto_evp
+ */
 
 const EVP_CIPHER *
 EVP_get_cipherbyname(const char *name)
@@ -807,6 +1394,26 @@ EVP_get_cipherbyname(const char *name)
 #define min(a,b) (((a)>(b))?(b):(a))
 #endif
 
+/**
+ * Provides a legancy string to key function, used in PEM files.
+ *
+ * New protocols should use new string to key functions like NIST
+ * SP56-800A or PKCS#5 v2.0 (see PKCS5_PBKDF2_HMAC_SHA1()).
+ *
+ * @param type type of cipher to use
+ * @param md message digest to use
+ * @param salt salt salt string, should be an binary 8 byte buffer.
+ * @param data the password/input key string.
+ * @param datalen length of data parameter.
+ * @param count iteration counter.
+ * @param keydata output keydata, needs to of the size EVP_CIPHER_key_length().
+ * @param ivdata output ivdata, needs to of the size EVP_CIPHER_block_size().
+ *
+ * @return the size of derived key.
+ *
+ * @ingroup hcrypto_evp
+ */
+
 int
 EVP_BytesToKey(const EVP_CIPHER *type,
               const EVP_MD *md, 
@@ -886,8 +1493,10 @@ EVP_BytesToKey(const EVP_CIPHER *type,
     return EVP_CIPHER_key_length(type);
 }
 
-/*
+/**
+ * Add all algorithms to the crypto core.
  *
+ * @ingroup hcrypto_core
  */
 
 void
@@ -896,12 +1505,25 @@ OpenSSL_add_all_algorithms(void)
     return;
 }
 
+/**
+ * Add all algorithms to the crypto core using configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
 void
 OpenSSL_add_all_algorithms_conf(void)
 {
     return;
 }
 
+/**
+ * Add all algorithms to the crypto core, but don't use the
+ * configuration file.
+ *
+ * @ingroup hcrypto_core
+ */
+
 void
 OpenSSL_add_all_algorithms_noconf(void)
 {
index a3fbc4c9cad0635f394b9649c15ed9d4d7bc41a2..4910ca01b8df87736e53e3fa079e6b6617e6f3cd 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: evp.h 18312 2006-10-07 17:21:48Z lha $ */
+/* $Id: evp.h 21687 2007-07-24 16:29:05Z lha $ */
 
 #ifndef HEIM_EVP_H
 #define HEIM_EVP_H 1
@@ -83,6 +83,9 @@
 #define EVP_rc2_cbc hc_EVP_rc2_cbc
 #define EVP_rc4 hc_EVP_rc4
 #define EVP_rc4_40 hc_EVP_rc4_40
+#define EVP_camellia_128_cbc hc_EVP_camellia_128_cbc
+#define EVP_camellia_192_cbc hc_EVP_camellia_192_cbc
+#define EVP_camellia_256_cbc hc_EVP_camellia_256_cbc
 #define EVP_sha hc_EVP_sha
 #define EVP_sha1 hc_EVP_sha1
 #define EVP_sha256 hc_EVP_sha256
@@ -180,6 +183,9 @@ const EVP_CIPHER * EVP_rc2_64_cbc(void);
 const EVP_CIPHER * EVP_rc2_cbc(void);
 const EVP_CIPHER * EVP_rc4(void);
 const EVP_CIPHER * EVP_rc4_40(void);
+const EVP_CIPHER * EVP_camellia_128_cbc(void);
+const EVP_CIPHER * EVP_camellia_192_cbc(void);
+const EVP_CIPHER * EVP_camellia_256_cbc(void);
 
 /*
  *
index 6c59758b11c65a2664706f14825b144c5aac5f18..d0433edef6dcc0d7254266428e5fdd8410cc96db 100644 (file)
@@ -1,6 +1,35 @@
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/*
+ * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
 
 #include <sys/types.h>
 #include <stdio.h>
index 376425788b0efe50a62248ec31e2922a535e4b8c..4487029f78fdcb1df9d529cd251281a15fdeecb8 100755 (executable)
@@ -2,7 +2,7 @@
   Name:     imath.c
   Purpose:  Arbitrary precision integer arithmetic routines.
   Author:   M. J. Fromberger <http://www.dartmouth.edu/~sting/>
-  Info:     $Id: imath.c 20854 2007-06-03 18:04:10Z lha $
+  Info:     $Id: imath.c 22648 2008-02-25 07:37:57Z lha $
 
   Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
 
@@ -1769,7 +1769,7 @@ mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **e
     return MP_RANGE;
 
   /* Skip leading whitespace */
-  while(isspace((int)*str))
+  while(isspace((unsigned char)*str))
     ++str;
 
   /* Handle leading sign tag (+/-, positive default) */
@@ -3135,7 +3135,7 @@ static int       s_ch2val(char c, int r)
   if(isdigit((unsigned char) c))
     out = c - '0';
   else if(r > 10 && isalpha((unsigned char) c))
-    out = toupper(c) - 'A' + 10;
+      out = toupper((unsigned char)c) - 'A' + 10;
   else
     return -1;
 
index 248fdde620845ee583555c29afee3061edb07684..79dd39eb76609b197a5e50654ccad8f1e7d1eecb 100644 (file)
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rand.c 21198 2007-06-20 05:10:41Z lha $");
+RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -189,13 +189,12 @@ RAND_file_name(char *filename, size_t size)
                pathp = 1;
        }
     }
-    if (e == NULL) {
-       struct passwd *pw = getpwuid(getuid()); 
-       if (pw) {
-           e = pw->pw_dir;
-           pathp = 1;
-       }
-    }
+    /* 
+     * Here we really want to call getpwuid(getuid()) but this will
+     * cause recursive lookups if the nss library uses
+     * gssapi/krb5/hcrypto to authenticate to the ldap servers.
+     */
+
     if (e == NULL)
        return NULL;
 
index a7b4371e4d491b457b000c1b595d66a0cbf80766..270857d1759e9c1bbf6f6ddee2725a651cb7739c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -35,7 +35,7 @@
 #include <config.h>
 #endif
 
-RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $");
+RCSID("$Id: rsa.c 22422 2008-01-13 09:43:59Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -46,12 +46,41 @@ RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $");
 
 #include <roken.h>
 
+/**
+ * @page page_rsa RSA - public-key cryptography
+ *
+ * RSA is named by its inventors (Ron Rivest, Adi Shamir, and Leonard
+ * Adleman) (published in 1977), patented expired in 21 September 2000.
+ *
+ * See the library functions here: @ref hcrypto_rsa
+ */
+
+/**
+ * Same as RSA_new_method() using NULL as engine.
+ *
+ * @return a newly allocated RSA object. Free with RSA_free().
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 RSA *
 RSA_new(void)
 {
     return RSA_new_method(NULL);
 }
 
+/**
+ * Allocate a new RSA object using the engine, if NULL is specified as
+ * the engine, use the default RSA engine as returned by
+ * ENGINE_get_default_RSA().
+ *
+ * @param engine Specific what ENGINE RSA provider should be used.
+ *
+ * @return a newly allocated RSA object. Free with RSA_free().
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 RSA *
 RSA_new_method(ENGINE *engine)
 {
@@ -87,6 +116,12 @@ RSA_new_method(ENGINE *engine)
     return rsa;
 }
 
+/**
+ * Free an allocation RSA object.
+ *
+ * @param rsa the RSA object to free.
+ * @ingroup hcrypto_rsa
+ */
 
 void
 RSA_free(RSA *rsa)
@@ -117,18 +152,51 @@ RSA_free(RSA *rsa)
     free(rsa);
 }
 
+/**
+ * Add an extra reference to the RSA object. The object should be free
+ * with RSA_free() to drop the reference.
+ *
+ * @param rsa the object to add reference counting too.
+ *
+ * @return the current reference count, can't safely be used except
+ * for debug printing.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 int
 RSA_up_ref(RSA *rsa)
 {
     return ++rsa->references;
 }
 
+/**
+ * Return the RSA_METHOD used for this RSA object.
+ *
+ * @param rsa the object to get the method from.
+ *
+ * @return the method used for this RSA object.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 const RSA_METHOD *
 RSA_get_method(const RSA *rsa)
 {
     return rsa->meth;
 }
 
+/**
+ * Set a new method for the RSA keypair.
+ *
+ * @param rsa rsa parameter.
+ * @param method the new method for the RSA parameter.
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 int
 RSA_set_method(RSA *rsa, const RSA_METHOD *method)
 {
@@ -144,6 +212,17 @@ RSA_set_method(RSA *rsa, const RSA_METHOD *method)
     return 1;
 }
 
+/**
+ * Set the application data for the RSA object.
+ *
+ * @param rsa the rsa object to set the parameter for
+ * @param arg the data object to store
+ *
+ * @return 1 on success.
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 int
 RSA_set_app_data(RSA *rsa, void *arg)
 {
@@ -151,6 +230,16 @@ RSA_set_app_data(RSA *rsa, void *arg)
     return 1;
 }
 
+/**
+ * Get the application data for the RSA object.
+ *
+ * @param rsa the rsa object to get the parameter for
+ *
+ * @return the data object
+ *
+ * @ingroup hcrypto_rsa
+ */
+
 void *
 RSA_get_app_data(RSA *rsa)
 {
@@ -296,7 +385,11 @@ RSA_null_method(void)
 }
 
 extern const RSA_METHOD hc_rsa_imath_method;
+#ifdef HAVE_GMP
+static const RSA_METHOD *default_rsa_method = &hc_rsa_gmp_method;
+#else
 static const RSA_METHOD *default_rsa_method = &hc_rsa_imath_method;
+#endif
 
 const RSA_METHOD *
 RSA_get_default_method(void)
index 575774dbde8d8ec5b7e8dab50c0eeda1d273b8b8..0f54ca0a4dd0c4ac5105dc71de09269d24043eae 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 /*
- * $Id: rsa.h 19734 2007-01-05 20:26:23Z lha $
+ * $Id: rsa.h 22269 2007-12-11 10:59:22Z lha $
  */
 
 #ifndef _HEIM_RSA_H
@@ -41,6 +41,7 @@
 /* symbol renaming */
 #define RSA_null_method hc_RSA_null_method
 #define RSA_imath_method hc_RSA_imath_method
+#define RSA_gmp_method hc_RSA_gmp_method
 #define RSA_new hc_RSA_new
 #define RSA_new_method hc_RSA_new_method
 #define RSA_free hc_RSA_free
@@ -133,6 +134,7 @@ struct RSA {
 
 const RSA_METHOD *RSA_null_method(void);
 const RSA_METHOD *RSA_imath_method(void);
+const RSA_METHOD *RSA_gmp_method(void);
 
 /*
  *
diff --git a/source/heimdal/lib/hdb/dbinfo.c b/source/heimdal/lib/hdb/dbinfo.c
new file mode 100644 (file)
index 0000000..d43e31b
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "hdb_locl.h"
+
+RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $");
+
+struct hdb_dbinfo {
+    char *label;
+    char *realm;
+    char *dbname;
+    char *mkey_file;
+    char *acl_file;
+    char *log_file;
+    const krb5_config_binding *binding;
+    struct hdb_dbinfo *next;
+};
+
+static int
+get_dbinfo(krb5_context context,
+          const krb5_config_binding *db_binding,
+          const char *label,
+          struct hdb_dbinfo **db)
+{
+    struct hdb_dbinfo *di;
+    const char *p;
+
+    *db = NULL;
+
+    p = krb5_config_get_string(context, db_binding, "dbname", NULL);
+    if(p == NULL)
+       return 0;
+
+    di = calloc(1, sizeof(*di));
+    if (di == NULL) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+    di->label = strdup(label);
+    di->dbname = strdup(p);
+
+    p = krb5_config_get_string(context, db_binding, "realm", NULL);
+    if(p)
+       di->realm = strdup(p);
+    p = krb5_config_get_string(context, db_binding, "mkey_file", NULL);
+    if(p)
+       di->mkey_file = strdup(p);
+    p = krb5_config_get_string(context, db_binding, "acl_file", NULL);
+    if(p)
+       di->acl_file = strdup(p);
+    p = krb5_config_get_string(context, db_binding, "log_file", NULL);
+    if(p)
+       di->log_file = strdup(p);
+
+    di->binding = db_binding;
+
+    *db = di;
+    return 0;
+}
+
+
+int
+hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
+{
+    const krb5_config_binding *db_binding;
+    struct hdb_dbinfo *di, **dt, *databases;
+    const char *default_dbname = HDB_DEFAULT_DB;
+    const char *default_mkey = HDB_DB_DIR "/m-key";
+    const char *default_acl = HDB_DB_DIR "/kadmind.acl";
+    const char *p;
+    int ret;
+
+    *dbp = NULL;
+    dt = NULL;
+    databases = NULL;
+
+    db_binding = krb5_config_get(context, NULL, krb5_config_list,
+                                "kdc", 
+                                "database",
+                                NULL);
+    if (db_binding) {
+
+       ret = get_dbinfo(context, db_binding, "default", &di);
+       if (ret == 0 && di) {
+           databases = di;
+           dt = &di->next;
+       }               
+
+       for ( ; db_binding != NULL; db_binding = db_binding->next) {
+
+           if (db_binding->type != krb5_config_list)
+               continue;
+
+           ret = get_dbinfo(context, db_binding->u.list, 
+                            db_binding->name, &di);
+           if (ret)
+               krb5_err(context, 1, ret, "failed getting realm");
+
+           if (di == NULL)
+               continue;
+
+           if (dt)
+               *dt = di;
+           else
+               databases = di;
+           dt = &di->next;
+
+       }
+    }
+
+    if(databases == NULL) {
+       /* if there are none specified, create one and use defaults */
+       di = calloc(1, sizeof(*di));
+       databases = di;
+       di->label = strdup("default");
+    }
+
+    for(di = databases; di; di = di->next) {
+       if(di->dbname == NULL) {
+           di->dbname = strdup(default_dbname);
+           if (di->mkey_file == NULL)
+               di->mkey_file = strdup(default_mkey);
+       }
+       if(di->mkey_file == NULL) {
+           p = strrchr(di->dbname, '.');
+           if(p == NULL || strchr(p, '/') != NULL)
+               /* final pathname component does not contain a . */
+               asprintf(&di->mkey_file, "%s.mkey", di->dbname);
+           else
+               /* the filename is something.else, replace .else with
+                   .mkey */
+               asprintf(&di->mkey_file, "%.*s.mkey", 
+                        (int)(p - di->dbname), di->dbname);
+       }
+       if(di->acl_file == NULL)
+           di->acl_file = strdup(default_acl);
+    }
+    *dbp = databases;
+    return 0;
+}
+
+
+struct hdb_dbinfo *
+hdb_dbinfo_get_next(struct hdb_dbinfo *dbp, struct hdb_dbinfo *dbprevp)
+{
+    if (dbprevp == NULL)
+       return dbp;
+    else
+       return dbprevp->next;
+}
+
+const char *
+hdb_dbinfo_get_label(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->label;
+}
+
+const char *
+hdb_dbinfo_get_realm(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->realm;
+}
+
+const char *
+hdb_dbinfo_get_dbname(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->dbname;
+}
+
+const char *
+hdb_dbinfo_get_mkey_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->mkey_file;
+}
+
+const char *
+hdb_dbinfo_get_acl_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->acl_file;
+}
+
+const char *
+hdb_dbinfo_get_log_file(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->log_file;
+}
+
+const krb5_config_binding *
+hdb_dbinfo_get_binding(krb5_context context, struct hdb_dbinfo *dbp)
+{
+    return dbp->binding;
+}
+
+void
+hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp)
+{
+    struct hdb_dbinfo *di, *ndi;
+
+    for(di = *dbp; di != NULL; di = ndi) {
+       ndi = di->next;
+       free (di->realm);
+       free (di->dbname);
+       if (di->mkey_file)
+           free (di->mkey_file);
+       free(di);
+    }
+    *dbp = NULL;
+}
+
+/**
+ * Return the directory where the hdb database resides.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return string pointing to directory.
+ */
+
+const char *
+hdb_db_dir(krb5_context context)
+{
+    return HDB_DB_DIR;
+}
+
+/**
+ * Return the default hdb database resides.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return string pointing to directory.
+ */
+
+const char *
+hdb_default_db(krb5_context context)
+{
+    return HDB_DEFAULT_DB;
+}
index 6d679fd48f71c7132dfa960b6b97e72f269d83b8..4c3d3eb1ab14ecb47b1498cce96eb075b5c0dd44 100644 (file)
@@ -42,6 +42,9 @@ hdb_db_create (
        HDB **/*db*/,
        const char */*filename*/);
 
+const char *
+hdb_db_dir (krb5_context /*context*/);
+
 const char *
 hdb_dbinfo_get_acl_file (
        krb5_context /*context*/,
@@ -62,6 +65,11 @@ hdb_dbinfo_get_label (
        krb5_context /*context*/,
        struct hdb_dbinfo */*dbp*/);
 
+const char *
+hdb_dbinfo_get_log_file (
+       krb5_context /*context*/,
+       struct hdb_dbinfo */*dbp*/);
+
 const char *
 hdb_dbinfo_get_mkey_file (
        krb5_context /*context*/,
@@ -77,6 +85,9 @@ hdb_dbinfo_get_realm (
        krb5_context /*context*/,
        struct hdb_dbinfo */*dbp*/);
 
+const char *
+hdb_default_db (krb5_context /*context*/);
+
 krb5_error_code
 hdb_enctype2key (
        krb5_context /*context*/,
index 830589388f8a984da3405f899537cc3a8f37bebd..742b92405d45ed96ca329631f74a44a58c9be00f 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: hdb.h 20535 2007-04-23 07:49:16Z lha $ */
+/* $Id: hdb.h 22198 2007-12-07 13:09:25Z lha $ */
 
 #ifndef __HDB_H__
 #define __HDB_H__
@@ -135,10 +135,6 @@ struct hdb_so_method {
     krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
 };
 
-#define HDB_DB_DIR "/var/heimdal"
-#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal"
-#define HDB_DB_FORMAT_ENTRY "hdb/db-format"
-
 typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*,
                                              hdb_entry_ex*, void*);
 extern krb5_kt_ops hdb_kt_ops;
index ad16075b247fe91b4af367d04060e0e20e008911..8f9d6fc4c2b67bda61e14c52cfe013e28b3f41d6 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: hdb_locl.h 12820 2003-09-10 21:54:58Z lha $ */
+/* $Id: hdb_locl.h 22209 2007-12-07 19:03:41Z lha $ */
 
 #ifndef __HDB_LOCL_H__
 #define __HDB_LOCL_H__
@@ -64,6 +64,9 @@
 #include <hdb.h>
 #include <hdb-private.h>
 
+#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal"
+#define HDB_DB_FORMAT_ENTRY "hdb/db-format"
+
 krb5_error_code
 hdb_ldb_create (
        krb5_context /*context*/,
index 9b870501201dccd40de18d11c8d13d5172ca9e99..60a58677fef99888d8e8c385619cbd438550a20d 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "hdb_locl.h"
 
-RCSID("$Id: keys.c 18819 2006-10-22 09:40:12Z lha $");
+RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $");
 
 /*
  * free all the memory used by (len, keys)
@@ -105,7 +105,7 @@ parse_key_set(krb5_context context, const char *key,
     salt->saltvalue.length = 0;
 
     for(i = 0; i < num_buf; i++) {
-       if(enctypes == NULL) {
+       if(enctypes == NULL && num_buf > 1) {
            /* this might be a etype specifier */
            /* XXX there should be a string_to_etypes handling
               special cases like `des' and `all' */
@@ -124,7 +124,9 @@ parse_key_set(krb5_context context, const char *key,
                } else
                    return ret;
            }
-       } else if(salt->salttype == 0) {
+           continue;
+       }
+       if(salt->salttype == 0) {
            /* interpret string as a salt specifier, if no etype
               is set, this sets default values */
            /* XXX should perhaps use string_to_salttype, but that
@@ -142,7 +144,10 @@ parse_key_set(krb5_context context, const char *key,
                }
                salt->salttype = KRB5_AFS3_SALT;
            }
-       } else {
+           continue;
+       }
+
+       {
            /* if there is a final string, use it as the string to
               salt with, this is mostly useful with null salt for
               v4 compat, and a cell name for afs compat */
@@ -239,7 +244,7 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset,
 /*
  * Generate the `key_set' from the [kadmin]default_keys statement. If
  * `no_salt' is set, salt is not important (and will not be set) since
- * its random keys that is going to be created.
+ * it's random keys that is going to be created.
  */
 
 krb5_error_code
index 02d87b6cf3efbd00560b1bc266e3cf2733504c1a..05cf71c59311c125d7bd09d1ed01f6d3667b69b5 100644 (file)
@@ -36,7 +36,7 @@
 #define O_BINARY 0
 #endif
 
-RCSID("$Id: mkey.c 17445 2006-05-05 10:37:46Z lha $");
+RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $");
 
 struct hdb_master_key_data {
     krb5_keytab_entry keytab;
@@ -129,6 +129,11 @@ read_master_keytab(krb5_context context, const char *filename,
     *mkey = NULL;
     while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) {
        p = calloc(1, sizeof(*p));
+       if(p == NULL) {
+           krb5_kt_end_seq_get(context, id, &cursor);
+           ret = ENOMEM;
+           goto out;
+       }
        p->keytab = entry;
        ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto);
        p->next = *mkey;
index bf8fe1be1a4c91bc7bd16dc94d7df89139ef1049..40260700b3fa2f7f734e7be948dda673bb776362 100644 (file)
 
 #include "hx_locl.h"
 #include <pkinit_asn1.h>
-RCSID("$Id: ca.c 21379 2007-06-28 07:38:17Z lha $");
+RCSID("$Id: ca.c 22456 2008-01-15 20:22:53Z lha $");
+
+/**
+ * @page page_ca Hx509 CA functions
+ *
+ * See the library functions here: @ref hx509_ca
+ */
 
 struct hx509_ca_tbs {
     hx509_name subject;
@@ -55,6 +61,19 @@ struct hx509_ca_tbs {
     CRLDistributionPoints crldp;
 };
 
+/**
+ * Allocate an to-be-signed certificate object that will be converted
+ * into an certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs returned to-be-signed certicate object, free with
+ * hx509_ca_tbs_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
 {
@@ -74,6 +93,14 @@ hx509_ca_tbs_init(hx509_context context, hx509_ca_tbs *tbs)
     return 0;
 }
 
+/**
+ * Free an To Be Signed object.
+ *
+ * @param tbs object to free.
+ *
+ * @ingroup hx509_ca
+ */
+
 void
 hx509_ca_tbs_free(hx509_ca_tbs *tbs)
 {
@@ -93,6 +120,19 @@ hx509_ca_tbs_free(hx509_ca_tbs *tbs)
     *tbs = NULL;
 }
 
+/**
+ * Set the absolute time when the certificate is valid from. If not
+ * set the current time will be used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param t time the certificated will start to be valid
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_notBefore(hx509_context context,
                           hx509_ca_tbs tbs,
@@ -102,6 +142,18 @@ hx509_ca_tbs_set_notBefore(hx509_context context,
     return 0;
 }
 
+/**
+ * Set the absolute time when the certificate is valid to.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param t time when the certificate will expire
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_notAfter(hx509_context context,
                           hx509_ca_tbs tbs,
@@ -111,6 +163,18 @@ hx509_ca_tbs_set_notAfter(hx509_context context,
     return 0;
 }
 
+/**
+ * Set the relative time when the certificiate is going to expire.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param delta seconds to the certificate is going to expire.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_notAfter_lifetime(hx509_context context,
                                   hx509_ca_tbs tbs,
@@ -130,12 +194,35 @@ static const struct units templatebits[] = {
     { NULL, 0 }
 };
 
+/**
+ * Make of template units, use to build flags argument to
+ * hx509_ca_tbs_set_template() with parse_units().
+ *
+ * @return an units structure.
+ *
+ * @ingroup hx509_ca
+ */
+
 const struct units *
 hx509_ca_tbs_template_units(void)
 {
     return templatebits;
 }
 
+/**
+ * Initialize the to-be-signed certificate object from a template certifiate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param flags bit field selecting what to copy from the template
+ * certifiate.
+ * @param cert template certificate.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_template(hx509_context context,
                          hx509_ca_tbs tbs,
@@ -170,12 +257,10 @@ hx509_ca_tbs_set_template(hx509_context context,
        tbs->notAfter = hx509_cert_get_notAfter(cert);
     if (flags & HX509_CA_TEMPLATE_SPKI) {
        free_SubjectPublicKeyInfo(&tbs->spki);
-       ret = hx509_cert_get_SPKI(cert, &tbs->spki);
+       ret = hx509_cert_get_SPKI(context, cert, &tbs->spki);
        tbs->flags.key = !ret;
-       if (ret) {
-           hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
+       if (ret)
            return ret;
-       }
     }
     if (flags & HX509_CA_TEMPLATE_KU) {
        KeyUsage ku;
@@ -202,6 +287,20 @@ hx509_ca_tbs_set_template(hx509_context context,
     return 0;
 }
 
+/**
+ * Make the to-be-signed certificate object a CA certificate. If the
+ * pathLenConstraint is negative path length constraint is used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param pathLenConstraint path length constraint, negative, no
+ * constraint.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_ca(hx509_context context,
                    hx509_ca_tbs tbs,
@@ -212,6 +311,20 @@ hx509_ca_tbs_set_ca(hx509_context context,
     return 0;
 }
 
+/**
+ * Make the to-be-signed certificate object a proxy certificate. If the
+ * pathLenConstraint is negative path length constraint is used.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param pathLenConstraint path length constraint, negative, no
+ * constraint.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_proxy(hx509_context context,
                       hx509_ca_tbs tbs,
@@ -223,6 +336,17 @@ hx509_ca_tbs_set_proxy(hx509_context context,
 }
 
 
+/**
+ * Make the to-be-signed certificate object a windows domain controller certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_domaincontroller(hx509_context context,
                                  hx509_ca_tbs tbs)
@@ -231,6 +355,20 @@ hx509_ca_tbs_set_domaincontroller(hx509_context context,
     return 0;
 }
 
+/**
+ * Set the subject public key info (SPKI) in the to-be-signed certificate
+ * object. SPKI is the public key and key related parameters in the
+ * certificate.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param spki subject public key info to use for the to-be-signed certificate object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_spki(hx509_context context,
                      hx509_ca_tbs tbs,
@@ -243,6 +381,19 @@ hx509_ca_tbs_set_spki(hx509_context context,
     return ret;
 }
 
+/**
+ * Set the serial number to use for to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param serialNumber serial number to use for the to-be-signed
+ * certificate object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_set_serialnumber(hx509_context context,
                              hx509_ca_tbs tbs,
@@ -255,6 +406,19 @@ hx509_ca_tbs_set_serialnumber(hx509_context context,
     return ret;
 }
 
+/**
+ * An an extended key usage to the to-be-signed certificate object.
+ * Duplicates will detected and not added.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param oid extended key usage to add.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_eku(hx509_context context,
                     hx509_ca_tbs tbs,
@@ -285,6 +449,20 @@ hx509_ca_tbs_add_eku(hx509_context context,
     return 0;
 }
 
+/**
+ * Add CRL distribution point URI to the to-be-signed certificate
+ * object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param uri uri to the CRL.
+ * @param issuername name of the issuer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
                            hx509_ca_tbs tbs,
@@ -325,6 +503,9 @@ hx509_ca_tbs_add_crl_dp_uri(hx509_context context,
 
     if (issuername) {
 #if 1
+       /**
+        * issuername not supported
+        */
        hx509_set_error_string(context, 0, EINVAL,
                               "CRLDistributionPoints.name.issuername not yet supported");
        return EINVAL;
@@ -372,6 +553,20 @@ out:
     return ret;
 }
 
+/**
+ * Add Subject Alternative Name otherName to the to-be-signed
+ * certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param oid the oid of the OtherName.
+ * @param os data in the other name.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_san_otherName(hx509_context context,
                               hx509_ca_tbs tbs,
@@ -388,6 +583,18 @@ hx509_ca_tbs_add_san_otherName(hx509_context context,
     return add_GeneralNames(&tbs->san, &gn);
 }
 
+/**
+ * Add Kerberos Subject Alternative Name to the to-be-signed
+ * certificate object. The principal string is a UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param principal Kerberos principal to add to the certificate.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
 
 int
 hx509_ca_tbs_add_san_pkinit(hx509_context context,
@@ -511,6 +718,19 @@ out:
     return ret;
 }
 
+/**
+ * Add Microsoft UPN Subject Alternative Name to the to-be-signed
+ * certificate object. The principal string is a UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param principal Microsoft UPN string.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_san_ms_upn(hx509_context context,
                            hx509_ca_tbs tbs,
@@ -519,6 +739,19 @@ hx509_ca_tbs_add_san_ms_upn(hx509_context context,
     return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);
 }
 
+/**
+ * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed
+ * certificate object. The jid is an UTF8 string.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param jid string of an a jabber id in UTF8.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_san_jid(hx509_context context,
                         hx509_ca_tbs tbs,
@@ -528,6 +761,22 @@ hx509_ca_tbs_add_san_jid(hx509_context context,
 }
 
 
+/**
+ * Add a Subject Alternative Name hostname to to-be-signed certificate
+ * object. A domain match starts with ., an exact match does not.
+ *
+ * Example of a an domain match: .domain.se matches the hostname
+ * host.domain.se.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param dnsname a hostame.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_san_hostname(hx509_context context,
                              hx509_ca_tbs tbs,
@@ -542,6 +791,19 @@ hx509_ca_tbs_add_san_hostname(hx509_context context,
     return add_GeneralNames(&tbs->san, &gn);
 }
 
+/**
+ * Add a Subject Alternative Name rfc822 (email address) to
+ * to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param rfc822Name a string to a email address.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_add_san_rfc822name(hx509_context context,
                                hx509_ca_tbs tbs,
@@ -556,6 +818,17 @@ hx509_ca_tbs_add_san_rfc822name(hx509_context context,
     return add_GeneralNames(&tbs->san, &gn);
 }
 
+/**
+ * Set the subject name of a to-be-signed certificate object.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param subject the name to set a subject.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
 
 int
 hx509_ca_tbs_set_subject(hx509_context context,
@@ -567,6 +840,20 @@ hx509_ca_tbs_set_subject(hx509_context context,
     return hx509_name_copy(context, subject, &tbs->subject);
 }
 
+/**
+ * Expand the the subject name in the to-be-signed certificate object
+ * using hx509_name_expand().
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param env enviroment variable to expand variables in the subject
+ * name, see hx509_env_init().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_tbs_subject_expand(hx509_context context,
                            hx509_ca_tbs tbs,
@@ -1148,6 +1435,30 @@ out:
 }
 
 
+/**
+ * Sign a to-be-signed certificate object with a issuer certificate. 
+ *
+ * The caller needs to at least have called the following functions on the
+ * to-be-signed certificate object:
+ * - hx509_ca_tbs_init()
+ * - hx509_ca_tbs_set_subject()
+ * - hx509_ca_tbs_set_spki()
+ *
+ * When done the to-be-signed certificate object should be freed with
+ * hx509_ca_tbs_free().
+ *
+ * When creating self-signed certificate use hx509_ca_sign_self() instead.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param signer the CA certificate object to sign with (need private key).
+ * @param certificate return cerificate, free with hx509_cert_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_sign(hx509_context context,
              hx509_ca_tbs tbs,
@@ -1179,6 +1490,19 @@ out:
     return ret;
 }
 
+/**
+ * Work just like hx509_ca_sign() but signs it-self.
+ *
+ * @param context A hx509 context.
+ * @param tbs object to be signed.
+ * @param signer private key to sign with.
+ * @param certificate return cerificate, free with hx509_cert_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_ca
+ */
+
 int
 hx509_ca_sign_self(hx509_context context,
                   hx509_ca_tbs tbs,
index b7f19d152a9f5342685ac899642a2f6a3eb6f8da..09c85bc08413818cc4c9cd3cdf1937b940b326f1 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: cert.c 21380 2007-06-28 07:38:38Z lha $");
+RCSID("$Id: cert.c 22583 2008-02-11 20:46:21Z lha $");
 #include "crypto-headers.h"
 #include <rtbl.h>
 
+/**
+ * @page page_cert The basic certificate
+ *
+ * The basic hx509 cerificate object in hx509 is hx509_cert. The
+ * hx509_cert object is representing one X509/PKIX certificate and
+ * associated attributes; like private key, friendly name, etc.
+ *
+ * A hx509_cert object is usully found via the keyset interfaces (@ref
+ * page_keyset), but its also possible to create a certificate
+ * directly from a parsed object with hx509_cert_init() and
+ * hx509_cert_init_data().
+ *
+ * See the library functions here: @ref hx509_cert
+ */
+
 struct hx509_verify_ctx_data {
     hx509_certs trust_anchors;
     int flags;
@@ -78,8 +93,16 @@ typedef struct hx509_name_constraints {
 #define GeneralSubtrees_SET(g,var) \
        (g)->len = (var)->len, (g)->val = (var)->val;
 
-/*
+/**
+ * Creates a hx509 context that most functions in the library
+ * uses. The context is only allowed to be used by one thread at each
+ * moment. Free the context with hx509_context_free().
  *
+ * @param context Returns a pointer to new hx509 context.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509
  */
 
 int
@@ -113,6 +136,19 @@ hx509_context_init(hx509_context *context)
     return 0;
 }
 
+/**
+ * Selects if the hx509_revoke_verify() function is going to require
+ * the existans of a revokation method (OSCP, CRL) or not. Note that
+ * hx509_verify_path(), hx509_cms_verify_signed(), and other function
+ * call hx509_revoke_verify().
+ * 
+ * @param context hx509 context to change the flag for.
+ * @param flag zero, revokation method required, non zero missing
+ * revokation method ok
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_context_set_missing_revoke(hx509_context context, int flag)
 {
@@ -122,6 +158,14 @@ hx509_context_set_missing_revoke(hx509_context context, int flag)
        context->flags &= ~HX509_CTX_VERIFY_MISSING_OK;
 }
 
+/**
+ * Free the context allocated by hx509_context_init().
+ * 
+ * @param context context to be freed.
+ *
+ * @ingroup hx509
+ */
+
 void
 hx509_context_free(hx509_context *context)
 {
@@ -139,7 +183,6 @@ hx509_context_free(hx509_context *context)
     *context = NULL;
 }
 
-
 /*
  *
  */
@@ -150,33 +193,6 @@ _hx509_get_cert(hx509_cert cert)
     return cert->data;
 }
 
-/*
- *
- */
-
-#if 0
-void
-_hx509_print_cert_subject(hx509_cert cert)
-{
-    char *subject_name;
-    hx509_name name;
-    int ret;
-
-    ret = hx509_cert_get_subject(cert, &name);
-    if (ret)
-       abort();
-       
-    ret = hx509_name_to_string(name, &subject_name);
-    hx509_name_free(&name);
-    if (ret)
-       abort();
-
-    printf("name: %s\n", subject_name);
-
-    free(subject_name);
-}
-#endif
-
 /*
  *
  */
@@ -187,6 +203,19 @@ _hx509_cert_get_version(const Certificate *t)
     return t->tbsCertificate.version ? *t->tbsCertificate.version + 1 : 1;
 }
 
+/**
+ * Allocate and init an hx509 certificate object from the decoded
+ * certificate `c´.
+ *
+ * @param context A hx509 context.
+ * @param c
+ * @param cert
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert)
 {
@@ -218,9 +247,29 @@ hx509_cert_init(hx509_context context, const Certificate *c, hx509_cert *cert)
     return ret;
 }
 
+/**
+ * Just like hx509_cert_init(), but instead of a decode certificate
+ * takes an pointer and length to a memory region that contains a
+ * DER/BER encoded certificate.
+ *
+ * If the memory region doesn't contain just the certificate and
+ * nothing more the function will fail with
+ * HX509_EXTRA_DATA_AFTER_STRUCTURE.
+ *
+ * @param context A hx509 context.
+ * @param ptr pointer to memory region containing encoded certificate.
+ * @param len length of memory region.
+ * @param cert a return pointer to a hx509 certificate object, will
+ * contain NULL on error.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_init_data(hx509_context context, 
-            const void *ptr,
+                    const void *ptr,
                     size_t len,
                     hx509_cert *cert)
 {
@@ -265,6 +314,15 @@ _hx509_cert_assign_key(hx509_cert cert, hx509_private_key private_key)
     return 0;
 }
 
+/**
+ * Free reference to the hx509 certificate object, if the refcounter
+ * reaches 0, the object if freed. Its allowed to pass in NULL.
+ *
+ * @param cert the cert to free.
+ *
+ * @ingroup hx509_cert
+ */
+
 void
 hx509_cert_free(hx509_cert cert)
 {
@@ -274,7 +332,7 @@ hx509_cert_free(hx509_cert cert)
        return;
 
     if (cert->ref <= 0)
-       _hx509_abort("refcount <= 0");
+       _hx509_abort("cert refcount <= 0 on free");
     if (--cert->ref > 0)
        return;
 
@@ -300,9 +358,21 @@ hx509_cert_free(hx509_cert cert)
     free(cert);
 }
 
+/**
+ * Add a reference to a hx509 certificate object.
+ *
+ * @param cert a pointer to an hx509 certificate object.
+ *
+ * @return the same object as is passed in.
+ *
+ * @ingroup hx509_cert
+ */
+
 hx509_cert
 hx509_cert_ref(hx509_cert cert)
 {
+    if (cert == NULL)
+       return NULL;
     if (cert->ref <= 0)
        _hx509_abort("cert refcount <= 0");
     cert->ref++;
@@ -311,6 +381,18 @@ hx509_cert_ref(hx509_cert cert)
     return cert;
 }
 
+/**
+ * Allocate an verification context that is used fo control the
+ * verification process. 
+ *
+ * @param context A hx509 context.
+ * @param ctx returns a pointer to a hx509_verify_ctx object.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
 int
 hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx)
 {
@@ -327,26 +409,75 @@ hx509_verify_init_ctx(hx509_context context, hx509_verify_ctx *ctx)
     return 0;
 }
 
+/**
+ * Free an hx509 verification context.
+ *
+ * @param ctx the context to be freed.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_destroy_ctx(hx509_verify_ctx ctx)
 {
-    if (ctx)
+    if (ctx) {
+       hx509_certs_free(&ctx->trust_anchors);
+       hx509_revoke_free(&ctx->revoke_ctx);
        memset(ctx, 0, sizeof(*ctx));
+    }
     free(ctx);
 }
 
+/**
+ * Set the trust anchors in the verification context, makes an
+ * reference to the keyset, so the consumer can free the keyset
+ * independent of the destruction of the verification context (ctx).
+ *
+ * @param ctx a verification context
+ * @param set a keyset containing the trust anchors.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_attach_anchors(hx509_verify_ctx ctx, hx509_certs set)
 {
-    ctx->trust_anchors = set;
+    ctx->trust_anchors = _hx509_certs_ref(set);
 }
 
+/**
+ * Attach an revocation context to the verfication context, , makes an
+ * reference to the revoke context, so the consumer can free the
+ * revoke context independent of the destruction of the verification
+ * context. If there is no revoke context, the verification process is
+ * NOT going to check any verification status.
+ *
+ * @param ctx a verification context.
+ * @param revoke_ctx a revoke context.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_attach_revoke(hx509_verify_ctx ctx, hx509_revoke_ctx revoke_ctx)
 {
-    ctx->revoke_ctx = revoke_ctx;
+    if (ctx->revoke_ctx)
+       hx509_revoke_free(&ctx->revoke_ctx);
+    ctx->revoke_ctx = _hx509_revoke_ref(revoke_ctx);
 }
 
+/**
+ * Set the clock time the the verification process is going to
+ * use. Used to check certificate in the past and future time. If not
+ * set the current time will be used.
+ *
+ * @param ctx a verification context.
+ * @param t the time the verifiation is using.
+ *
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
 {
@@ -354,12 +485,32 @@ hx509_verify_set_time(hx509_verify_ctx ctx, time_t t)
     ctx->time_now = t;
 }
 
+/**
+ * Set the maximum depth of the certificate chain that the path
+ * builder is going to try.
+ *
+ * @param ctx a verification context
+ * @param max_depth maxium depth of the certificate chain, include
+ * trust anchor.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_set_max_depth(hx509_verify_ctx ctx, unsigned int max_depth)
 {
     ctx->max_depth = max_depth;
 }
 
+/**
+ * Allow or deny the use of proxy certificates
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, allow proxy certificates.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
 {
@@ -369,6 +520,17 @@ hx509_verify_set_proxy_certificate(hx509_verify_ctx ctx, int boolean)
        ctx->flags &= ~HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE;
 }
 
+/**
+ * Select strict RFC3280 verification of certificiates. This means
+ * checking key usage on CA certificates, this will make version 1
+ * certificiates unuseable.
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, use strict verification.
+ *
+ * @ingroup hx509_verify
+ */
+
 void
 hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean)
 {
@@ -378,6 +540,20 @@ hx509_verify_set_strict_rfc3280_verification(hx509_verify_ctx ctx, int boolean)
        ctx->flags &= ~HX509_VERIFY_CTX_F_REQUIRE_RFC3280;
 }
 
+/**
+ * Allow using the operating system builtin trust anchors if no other
+ * trust anchors are configured.
+ *
+ * @param ctx a verification context
+ * @param boolean if non zero, useing the operating systems builtin
+ * trust anchors.
+ *
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 void
 hx509_verify_ctx_f_allow_default_trustanchors(hx509_verify_ctx ctx, int boolean)
 {
@@ -512,6 +688,15 @@ add_to_list(hx509_octet_string_list *list, const heim_octet_string *entry)
     return 0;
 }
 
+/**
+ * Free a list of octet strings returned by another hx509 library
+ * function.
+ *
+ * @param list list to be freed.
+ *
+ * @ingroup hx509_misc
+ */
+
 void
 hx509_free_octet_string_list(hx509_octet_string_list *list)
 {
@@ -523,8 +708,26 @@ hx509_free_octet_string_list(hx509_octet_string_list *list)
     list->len = 0;
 }
 
+/**
+ * Return a list of subjectAltNames specified by oid in the
+ * certificate. On error the 
+ *
+ * The returned list of octet string should be freed with
+ * hx509_free_octet_string_list().
+ *
+ * @param context A hx509 context.
+ * @param cert a hx509 certificate object.
+ * @param oid an oid to for SubjectAltName.
+ * @param list list of matching SubjectAltName.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
-hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
+hx509_cert_find_subjectAltName_otherName(hx509_context context,
+                                        hx509_cert cert,
                                         const heim_oid *oid,
                                         hx509_octet_string_list *list)
 {
@@ -541,9 +744,11 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
        if (ret == HX509_EXTENSION_NOT_FOUND) {
            ret = 0;
            break;
-       } else if (ret != 0)
-           break;
-
+       } else if (ret != 0) {
+           hx509_set_error_string(context, 0, ret, "Error searching for SAN");
+           hx509_free_octet_string_list(list);
+           return ret;
+       }
 
        for (j = 0; j < sa.len; j++) {
            if (sa.val[j].element == choice_GeneralName_otherName &&
@@ -551,6 +756,10 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
            {
                ret = add_to_list(list, &sa.val[j].u.otherName.value);
                if (ret) {
+                   hx509_set_error_string(context, 0, ret, 
+                                          "Error adding an exra SAN to "
+                                          "return list");
+                   hx509_free_octet_string_list(list);
                    free_GeneralNames(&sa);
                    return ret;
                }
@@ -558,7 +767,7 @@ hx509_cert_find_subjectAltName_otherName(hx509_cert cert,
        }
        free_GeneralNames(&sa);
     }
-    return ret;
+    return 0;
 }
 
 
@@ -605,6 +814,12 @@ check_key_usage(hx509_context context, const Certificate *cert,
     return 0;
 }
 
+/*
+ * Return 0 on matching key usage 'flags' for 'cert', otherwise return
+ * an error code. If 'req_present' the existance is required of the
+ * KeyUsage extension.
+ */
+
 int
 _hx509_check_key_usage(hx509_context context, hx509_cert cert, 
                       unsigned flags, int req_present)
@@ -678,10 +893,13 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
     int diff;
     AuthorityKeyIdentifier ai;
     SubjectKeyIdentifier si;
-    int ret_ai, ret_si;
+    int ret_ai, ret_si, ret;
 
-    diff = _hx509_name_cmp(&issuer->tbsCertificate.subject, 
-                          &subject->tbsCertificate.issuer);
+    ret = _hx509_name_cmp(&issuer->tbsCertificate.subject, 
+                         &subject->tbsCertificate.issuer,
+                         &diff);
+    if (ret)
+       return ret;
     if (diff)
        return diff;
     
@@ -689,7 +907,7 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
     memset(&si, 0, sizeof(si));
 
     /*
-     * Try to find AuthorityKeyIdentifier, if its not present in the
+     * Try to find AuthorityKeyIdentifier, if it's not present in the
      * subject certificate nor the parent.
      */
 
@@ -736,8 +954,11 @@ _hx509_cert_is_parent_cmp(const Certificate *subject,
        name.u.rdnSequence = 
            ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
 
-       diff = _hx509_name_cmp(&issuer->tbsCertificate.subject, 
-                              &name);
+       ret = _hx509_name_cmp(&issuer->tbsCertificate.subject, 
+                             &name,
+                             &diff);
+       if (ret)
+           return ret;
        if (diff)
            return diff;
        diff = 0;
@@ -776,13 +997,22 @@ certificate_is_anchor(hx509_context context,
 }
 
 static int
-certificate_is_self_signed(const Certificate *cert)
-{
-    return _hx509_cert_is_parent_cmp(cert, cert, 1) == 0;
+certificate_is_self_signed(hx509_context context,
+                          const Certificate *cert,
+                          int *self_signed)
+{
+    int ret, diff;
+    ret = _hx509_name_cmp(&cert->tbsCertificate.subject, 
+                         &cert->tbsCertificate.issuer, &diff);
+    *self_signed = (diff == 0);
+    if (ret)
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to check if self signed");
+    return ret;
 }
 
 /*
- * The subjectName is "null" when its empty set of relative DBs.
+ * The subjectName is "null" when it's empty set of relative DBs.
  */
 
 static int
@@ -1032,9 +1262,9 @@ _hx509_calculate_path(hx509_context context,
     return 0;
 }
 
-static int
-AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p,
-                       const AlgorithmIdentifier *q)
+int
+_hx509_AlgorithmIdentifier_cmp(const AlgorithmIdentifier *p,
+                              const AlgorithmIdentifier *q)
 {
     int diff;
     diff = der_heim_oid_cmp(&p->algorithm, &q->algorithm);
@@ -1061,8 +1291,8 @@ _hx509_Certificate_cmp(const Certificate *p, const Certificate *q)
     diff = der_heim_bit_string_cmp(&p->signatureValue, &q->signatureValue);
     if (diff)
        return diff;
-    diff = AlgorithmIdentifier_cmp(&p->signatureAlgorithm, 
-                                  &q->signatureAlgorithm);
+    diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm, 
+                                         &q->signatureAlgorithm);
     if (diff)
        return diff;
     diff = der_heim_octet_string_cmp(&p->tbsCertificate._save,
@@ -1070,24 +1300,77 @@ _hx509_Certificate_cmp(const Certificate *p, const Certificate *q)
     return diff;
 }
 
+/**
+ * Compare to hx509 certificate object, useful for sorting.
+ *
+ * @param p a hx509 certificate object.
+ * @param q a hx509 certificate object.
+ *
+ * @return 0 the objects are the same, returns > 0 is p is "larger"
+ * then q, < 0 if p is "smaller" then q.
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_cmp(hx509_cert p, hx509_cert q)
 {
     return _hx509_Certificate_cmp(p->data, q->data);
 }
 
+/**
+ * Return the name of the issuer of the hx509 certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_get_issuer(hx509_cert p, hx509_name *name)
 {
     return _hx509_name_from_Name(&p->data->tbsCertificate.issuer, name);
 }
 
+/**
+ * Return the name of the subject of the hx509 certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free(). See also hx509_cert_get_base_subject().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_get_subject(hx509_cert p, hx509_name *name)
 {
     return _hx509_name_from_Name(&p->data->tbsCertificate.subject, name);
 }
 
+/**
+ * Return the name of the base subject of the hx509 certificate. If
+ * the certiicate is a verified proxy certificate, the this function
+ * return the base certificate (root of the proxy chain). If the proxy
+ * certificate is not verified with the base certificate
+ * HX509_PROXY_CERTIFICATE_NOT_CANONICALIZED is returned.
+ *
+ * @param context a hx509 context.
+ * @param c a hx509 certificate object.
+ * @param name a pointer to a hx509 name, should be freed by
+ * hx509_name_free(). See also hx509_cert_get_subject().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_get_base_subject(hx509_context context, hx509_cert c,
                            hx509_name *name)
@@ -1104,37 +1387,120 @@ hx509_cert_get_base_subject(hx509_context context, hx509_cert c,
     return _hx509_name_from_Name(&c->data->tbsCertificate.subject, name);
 }
 
+/**
+ * Get serial number of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ * @param i serial number, should be freed ith der_free_heim_integer().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_get_serialnumber(hx509_cert p, heim_integer *i)
 {
     return der_copy_heim_integer(&p->data->tbsCertificate.serialNumber, i);
 }
 
+/**
+ * Get notBefore time of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ *
+ * @return return not before time
+ *
+ * @ingroup hx509_cert
+ */
+
 time_t
 hx509_cert_get_notBefore(hx509_cert p)
 {
     return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notBefore);
 }
 
+/**
+ * Get notAfter time of the certificate.
+ *
+ * @param p a hx509 certificate object.
+ *
+ * @return return not after time.
+ *
+ * @ingroup hx509_cert
+ */
+
 time_t
 hx509_cert_get_notAfter(hx509_cert p)
 {
     return _hx509_Time2time_t(&p->data->tbsCertificate.validity.notAfter);
 }
 
+/**
+ * Get the SubjectPublicKeyInfo structure from the hx509 certificate.
+ *
+ * @param context a hx509 context.
+ * @param p a hx509 certificate object.
+ * @param spki SubjectPublicKeyInfo, should be freed with
+ * free_SubjectPublicKeyInfo().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_cert_get_SPKI(hx509_context context, hx509_cert p, SubjectPublicKeyInfo *spki)
+{
+    int ret;
+
+    ret = copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo, spki);
+    if (ret)
+       hx509_set_error_string(context, 0, ret, "Failed to copy SPKI");
+    return ret;
+}
+
+/**
+ * Get the AlgorithmIdentifier from the hx509 certificate.
+ *
+ * @param context a hx509 context.
+ * @param p a hx509 certificate object.
+ * @param alg AlgorithmIdentifier, should be freed with
+ * free_AlgorithmIdentifier().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
-hx509_cert_get_SPKI(hx509_cert p, SubjectPublicKeyInfo *spki)
+hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context,
+                                       hx509_cert p, 
+                                       AlgorithmIdentifier *alg)
 {
-    return copy_SubjectPublicKeyInfo(&p->data->tbsCertificate.subjectPublicKeyInfo,
-                                    spki);
+    int ret;
+
+    ret = copy_AlgorithmIdentifier(&p->data->tbsCertificate.subjectPublicKeyInfo.algorithm, alg);
+    if (ret)
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to copy SPKI AlgorithmIdentifier");
+    return ret;
 }
 
+
 hx509_private_key
 _hx509_cert_private_key(hx509_cert p)
 {
     return p->private_key;
 }
 
+int
+hx509_cert_have_private_key(hx509_cert p)
+{
+    return p->private_key ? 1 : 0;
+}
+
+
 int
 _hx509_cert_private_key_exportable(hx509_cert p)
 {
@@ -1253,9 +1619,14 @@ match_RDN(const RelativeDistinguishedName *c,
        return HX509_NAME_CONSTRAINT_ERROR;
     
     for (i = 0; i < n->len; i++) {
+       int diff, ret;
+
        if (der_heim_oid_cmp(&c->val[i].type, &n->val[i].type) != 0)
            return HX509_NAME_CONSTRAINT_ERROR;
-       if (_hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value) != 0)
+       ret = _hx509_name_ds_cmp(&c->val[i].value, &n->val[i].value, &diff);
+       if (ret)
+           return ret;
+       if (diff != 0)
            return HX509_NAME_CONSTRAINT_ERROR;
     }
     return 0;
@@ -1316,7 +1687,7 @@ match_general_name(const GeneralName *c, const GeneralName *n, int *match)
                return HX509_NAME_CONSTRAINT_ERROR;
            if (strcasecmp(s + 1 + len2 - len1, c->u.rfc822Name) != 0)
                return HX509_NAME_CONSTRAINT_ERROR;
-           if (len1 < len2 && s[len2 - len1] != '.')
+           if (len1 < len2 && s[len2 - len1 + 1] != '.')
                return HX509_NAME_CONSTRAINT_ERROR;
        }
        *match = 1;
@@ -1387,7 +1758,6 @@ match_alt_name(const GeneralName *n, const Certificate *c,
        }
        free_GeneralNames(&sa);
     } while (1);
-
     return ret;
 }
 
@@ -1457,7 +1827,10 @@ check_name_constraints(hx509_context context,
            }
            /* allow null subjectNames, they wont matches anything */
            if (match == 0 && !subject_null_p(c)) {
-               hx509_clear_error_string(context);
+               hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
+                                      "Error verify constraints, "
+                                      "certificate didn't match any "
+                                      "permitted subtree");
                return HX509_VERIFY_CONSTRAINTS;
            }
        }
@@ -1469,7 +1842,10 @@ check_name_constraints(hx509_context context,
                return ret;
            }
            if (match) {
-               hx509_clear_error_string(context);
+               hx509_set_error_string(context, 0, HX509_VERIFY_CONSTRAINTS,
+                                      "Error verify constraints, "
+                                      "certificate included in excluded "
+                                      "subtree");
                return HX509_VERIFY_CONSTRAINTS;
            }
        }
@@ -1487,6 +1863,21 @@ free_name_constraints(hx509_name_constraints *nc)
     free(nc->val);
 }
 
+/**
+ * Build and verify the path for the certificate to the trust anchor
+ * specified in the verify context. The path is constructed from the
+ * certificate, the pool and the trust anchors.
+ *
+ * @param context A hx509 context.
+ * @param ctx A hx509 verification context.
+ * @param cert the certificate to build the path from.
+ * @param pool A keyset of certificates to build the chain from.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
 int
 hx509_verify_path(hx509_context context,
                  hx509_verify_ctx ctx,
@@ -1495,10 +1886,7 @@ hx509_verify_path(hx509_context context,
 {
     hx509_name_constraints nc;
     hx509_path path;
-#if 0
-    const AlgorithmIdentifier *alg_id;
-#endif
-    int ret, i, proxy_cert_depth;
+    int ret, i, proxy_cert_depth, selfsigned_depth, diff;
     enum certtype type;
     Name proxy_issuer;
     hx509_certs anchors = NULL;
@@ -1538,10 +1926,6 @@ hx509_verify_path(hx509_context context,
     if (ret)
        goto out;
 
-#if 0
-    alg_id = path.val[path->len - 1]->data->tbsCertificate.signature;
-#endif
-
     /*
      * Check CA and proxy certificate chain from the top of the
      * certificate chain. Also check certificate is valid with respect
@@ -1550,6 +1934,7 @@ hx509_verify_path(hx509_context context,
      */
 
     proxy_cert_depth = 0;
+    selfsigned_depth = 0;
 
     if (ctx->flags & HX509_VERIFY_CTX_F_ALLOW_PROXY_CERTIFICATE)
        type = PROXY_CERT;
@@ -1570,6 +1955,7 @@ hx509_verify_path(hx509_context context,
 
        switch (type) {
        case CA_CERT:
+
            /* XXX make constants for keyusage */
            ret = check_key_usage(context, c, 1 << 5,
                                  REQUIRE_RFC3280(ctx) ? TRUE : FALSE);
@@ -1578,6 +1964,18 @@ hx509_verify_path(hx509_context context,
                                       "Key usage missing from CA certificate");
                goto out;
            }
+
+           /* self signed cert doesn't add to path length */
+           if (i + 1 != path.len) {
+               int selfsigned;
+
+               ret = certificate_is_self_signed(context, c, &selfsigned);
+               if (ret)
+                   goto out;
+               if (selfsigned) 
+                   selfsigned_depth++;
+           }
+
            break;
        case PROXY_CERT: {
            ProxyCertInfo info;     
@@ -1624,8 +2022,12 @@ hx509_verify_path(hx509_context context,
                 */
 
                if (proxy_cert_depth) {
-                   ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject);
+                   ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.subject, &diff);
                    if (ret) {
+                       hx509_set_error_string(context, 0, ret, "Out of memory");
+                       goto out;
+                   }
+                   if (diff) {
                        ret = HX509_PROXY_CERT_NAME_WRONG;
                        hx509_set_error_string(context, 0, ret,
                                               "Base proxy name not right");
@@ -1658,8 +2060,12 @@ hx509_verify_path(hx509_context context,
                free_RelativeDistinguishedName(&proxy_issuer.u.rdnSequence.val[j - 1]);
                proxy_issuer.u.rdnSequence.len -= 1;
 
-               ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer);
-               if (ret != 0) {
+               ret = _hx509_name_cmp(&proxy_issuer, &c->tbsCertificate.issuer, &diff);
+               if (ret) {
+                   hx509_set_error_string(context, 0, ret, "Out of memory");
+                   goto out;
+               }
+               if (diff != 0) {
                    ret = HX509_PROXY_CERT_NAME_WRONG;
                    hx509_set_error_string(context, 0, ret,
                                           "Proxy issuer name not as expected");
@@ -1685,9 +2091,13 @@ hx509_verify_path(hx509_context context,
             */
            if (proxy_cert_depth) {
 
-               ret = _hx509_name_cmp(&proxy_issuer,
-                                     &c->tbsCertificate.subject);
+               ret = _hx509_name_cmp(&proxy_issuer, 
+                                     &c->tbsCertificate.subject, &diff);
                if (ret) {
+                   hx509_set_error_string(context, 0, ret, "out of memory");
+                   goto out;
+               }
+               if (diff) {
                    ret = HX509_PROXY_CERT_NAME_WRONG;
                    hx509_clear_error_string(context);
                    goto out;
@@ -1705,7 +2115,8 @@ hx509_verify_path(hx509_context context,
            break;
        }
 
-       ret = check_basic_constraints(context, c, type, i - proxy_cert_depth);
+       ret = check_basic_constraints(context, c, type, 
+                                     i - proxy_cert_depth - selfsigned_depth);
        if (ret)
            goto out;
            
@@ -1742,22 +2153,16 @@ hx509_verify_path(hx509_context context,
 
     for (ret = 0, i = path.len - 1; i >= 0; i--) {
        Certificate *c;
+       int selfsigned;
 
        c = _hx509_get_cert(path.val[i]);
 
-#if 0
-       /* check that algorithm and parameters is the same */
-       /* XXX this is wrong */
-       ret = alg_cmp(&c->tbsCertificate.signature, alg_id);
-       if (ret) {
-           hx509_clear_error_string(context);
-           ret = HX509_PATH_ALGORITHM_CHANGED;
+       ret = certificate_is_self_signed(context, c, &selfsigned);
+       if (ret)
            goto out;
-       }
-#endif
 
        /* verify name constraints, not for selfsigned and anchor */
-       if (!certificate_is_self_signed(c) || i == path.len - 1) {
+       if (!selfsigned || i + 1 != path.len) {
            ret = check_name_constraints(context, &nc, c);
            if (ret) {
                goto out;
@@ -1813,12 +2218,6 @@ hx509_verify_path(hx509_context context,
        hx509_certs_free(&certs);
     }
 
-#if 0
-    for (i = path.len - 1; i >= 0; i--) {
-       _hx509_print_cert_subject(path.val[i]);
-    }
-#endif
-
     /*
      * Verify signatures, do this backward so public key working
      * parameter is passed up from the anchor up though the chain.
@@ -1830,11 +2229,17 @@ hx509_verify_path(hx509_context context,
        c = _hx509_get_cert(path.val[i]);
 
        /* is last in chain (trust anchor) */
-       if (i == path.len - 1) {
+       if (i + 1 == path.len) {
+           int selfsigned;
+
            signer = path.val[i]->data;
 
+           ret = certificate_is_self_signed(context, signer, &selfsigned);
+           if (ret)
+               goto out;
+
            /* if trust anchor is not self signed, don't check sig */
-           if (!certificate_is_self_signed(signer))
+           if (!selfsigned)
                continue;
        } else {
            /* take next certificate in chain */
@@ -1863,6 +2268,20 @@ out:
     return ret;
 }
 
+/**
+ * Verify a signature made using the private key of an certificate.
+ *
+ * @param context A hx509 context.
+ * @param signer the certificate that made the signature.
+ * @param alg algorthm that was used to sign the data.
+ * @param data the data that was signed.
+ * @param sig the sigature to verify.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_crypto
+ */
+
 int
 hx509_verify_signature(hx509_context context,
                       const hx509_cert signer,
@@ -1873,7 +2292,26 @@ hx509_verify_signature(hx509_context context,
     return _hx509_verify_signature(context, signer->data, alg, data, sig);
 }
 
-#define HX509_VHN_F_ALLOW_NO_MATCH 1
+
+/**
+ * Verify that the certificate is allowed to be used for the hostname
+ * and address.
+ *
+ * @param context A hx509 context.
+ * @param cert the certificate to match with
+ * @param flags Flags to modify the behavior:
+ * - HX509_VHN_F_ALLOW_NO_MATCH no match is ok
+ * @param type type of hostname:
+ * - HX509_HN_HOSTNAME for plain hostname.
+ * - HX509_HN_DNSSRV for DNS SRV names.
+ * @param hostname the hostname to check
+ * @param sa address of the host
+ * @param sa_size length of address
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
 
 int
 hx509_verify_hostname(hx509_context context,
@@ -1984,6 +2422,19 @@ _hx509_set_cert_attribute(hx509_context context,
     return 0;
 }
 
+/**
+ * Get an external attribute for the certificate, examples are
+ * friendly name and id.
+ *
+ * @param cert hx509 certificate object to search
+ * @param oid an oid to search for.
+ *
+ * @return an hx509_cert_attribute, only valid as long as the
+ * certificate is referenced.
+ *
+ * @ingroup hx509_cert
+ */
+
 hx509_cert_attribute
 hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid)
 {
@@ -1994,6 +2445,17 @@ hx509_cert_get_attribute(hx509_cert cert, const heim_oid *oid)
     return NULL;
 }
 
+/**
+ * Set the friendly name on the certificate.
+ *
+ * @param cert The certificate to set the friendly name on
+ * @param name Friendly name.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_set_friendly_name(hx509_cert cert, const char *name)
 {
@@ -2005,6 +2467,16 @@ hx509_cert_set_friendly_name(hx509_cert cert, const char *name)
     return 0;
 }
 
+/**
+ * Get friendly name of the certificate.
+ *
+ * @param cert cert to get the friendly name from.
+ *
+ * @return an friendly name or NULL if there is. The friendly name is
+ * only valid as long as the certificate is referenced.
+ *
+ * @ingroup hx509_cert
+ */
 
 const char *
 hx509_cert_get_friendly_name(hx509_cert cert)
@@ -2056,6 +2528,17 @@ _hx509_query_clear(hx509_query *q)
     memset(q, 0, sizeof(*q));
 }
 
+/**
+ * Allocate an query controller. Free using hx509_query_free().
+ *
+ * @param context A hx509 context.
+ * @param q return pointer to a hx509_query.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_query_alloc(hx509_context context, hx509_query **q)
 {
@@ -2065,6 +2548,17 @@ hx509_query_alloc(hx509_context context, hx509_query **q)
     return 0;
 }
 
+/**
+ * Set match options for the hx509 query controller.
+ *
+ * @param q query controller.
+ * @param option options to control the query controller.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 void
 hx509_query_match_option(hx509_query *q, hx509_query_option option)
 {
@@ -2087,6 +2581,19 @@ hx509_query_match_option(hx509_query *q, hx509_query_option option)
     }
 }
 
+/**
+ * Set the issuer and serial number of match in the query
+ * controller. The function make copies of the isser and serial number.
+ *
+ * @param q a hx509 query controller
+ * @param issuer issuer to search for
+ * @param serialNumber the serialNumber of the issuer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_query_match_issuer_serial(hx509_query *q,
                                const Name *issuer, 
@@ -2123,6 +2630,16 @@ hx509_query_match_issuer_serial(hx509_query *q,
     return 0;
 }
 
+/**
+ * Set the query controller to match on a friendly name
+ *
+ * @param q a hx509 query controller.
+ * @param name a friendly name to match on
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
 
 int
 hx509_query_match_friendly_name(hx509_query *q, const char *name)
@@ -2136,6 +2653,63 @@ hx509_query_match_friendly_name(hx509_query *q, const char *name)
     return 0;
 }
 
+/**
+ * Set the query controller to require an one specific EKU (extended
+ * key usage). Any previous EKU matching is overwitten. If NULL is
+ * passed in as the eku, the EKU requirement is reset.
+ *
+ * @param q a hx509 query controller.
+ * @param eku an EKU to match on.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
+int
+hx509_query_match_eku(hx509_query *q, const heim_oid *eku)
+{
+    int ret;
+
+    if (eku == NULL) {
+       if (q->eku) {
+           der_free_oid(q->eku);
+           free(q->eku);
+           q->eku = NULL;
+       }
+       q->match &= ~HX509_QUERY_MATCH_EKU;
+    } else {
+       if (q->eku) {
+           der_free_oid(q->eku);
+       } else {
+           q->eku = calloc(1, sizeof(*q->eku));
+           if (q->eku == NULL)
+               return ENOMEM;
+       }
+       ret = der_copy_oid(eku, q->eku);
+       if (ret) {
+           free(q->eku);
+           q->eku = NULL;
+           return ret;
+       }
+       q->match |= HX509_QUERY_MATCH_EKU;
+    }
+    return 0;
+}
+
+/**
+ * Set the query controller to match using a specific match function.
+ *
+ * @param q a hx509 query controller.
+ * @param func function to use for matching, if the argument is NULL,
+ * the match function is removed.
+ * @param ctx context passed to the function.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_query_match_cmp_func(hx509_query *q,
                           int (*func)(void *, hx509_cert),
@@ -2150,24 +2724,36 @@ hx509_query_match_cmp_func(hx509_query *q,
     return 0;
 }
 
+/**
+ * Free the query controller.
+ *
+ * @param context A hx509 context.
+ * @param q a pointer to the query controller.
+ *
+ * @ingroup hx509_cert
+ */
 
 void
 hx509_query_free(hx509_context context, hx509_query *q)
 {
+    if (q == NULL)
+       return;
+
     if (q->serial) {
        der_free_heim_integer(q->serial);
        free(q->serial);
-       q->serial = NULL;
     }
     if (q->issuer_name) {
        free_Name(q->issuer_name);
        free(q->issuer_name);
-       q->issuer_name = NULL;
     }
-    if (q) {
-       free(q->friendlyname);
-       memset(q, 0, sizeof(*q));
+    if (q->eku) {
+       der_free_oid(q->eku);
+       free(q->eku);
     }
+    if (q->friendlyname)
+       free(q->friendlyname);
+    memset(q, 0, sizeof(*q));
     free(q);
 }
 
@@ -2175,6 +2761,7 @@ int
 _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert cert)
 {
     Certificate *c = _hx509_get_cert(cert);
+    int ret, diff;
 
     _hx509_query_statistic(context, 1, q);
 
@@ -2190,17 +2777,20 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
        && der_heim_integer_cmp(&c->tbsCertificate.serialNumber, q->serial) != 0)
        return 0;
 
-    if ((q->match & HX509_QUERY_MATCH_ISSUER_NAME)
-       && _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name) != 0)
-       return 0;
+    if (q->match & HX509_QUERY_MATCH_ISSUER_NAME) {
+       ret = _hx509_name_cmp(&c->tbsCertificate.issuer, q->issuer_name, &diff);
+       if (ret || diff)
+           return 0;
+    }
 
-    if ((q->match & HX509_QUERY_MATCH_SUBJECT_NAME)
-       && _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name) != 0)
-       return 0;
+    if (q->match & HX509_QUERY_MATCH_SUBJECT_NAME) {
+       ret = _hx509_name_cmp(&c->tbsCertificate.subject, q->subject_name, &diff);
+       if (ret || diff)
+           return 0;
+    }
 
     if (q->match & HX509_QUERY_MATCH_SUBJECT_KEY_ID) {
        SubjectKeyIdentifier si;
-       int ret;
 
        ret = _hx509_find_extension_subject_key_id(c, &si);
        if (ret == 0) {
@@ -2264,14 +2854,13 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
            return 0;
     }
     if (q->match & HX509_QUERY_MATCH_FUNCTION) {
-       int ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
+       ret = (*q->cmp_func)(q->cmp_func_ctx, cert);
        if (ret != 0)
            return 0;
     }
 
     if (q->match & HX509_QUERY_MATCH_KEY_HASH_SHA1) {
        heim_octet_string os;
-       int ret;
 
        os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
        os.length = 
@@ -2296,12 +2885,26 @@ _hx509_query_match_cert(hx509_context context, const hx509_query *q, hx509_cert
            return 0;
     }
 
+    /* If an EKU is required, check the cert for it. */
+    if ((q->match & HX509_QUERY_MATCH_EKU) &&
+       hx509_cert_check_eku(context, cert, q->eku, 0))
+       return 0;
+
     if (q->match & ~HX509_QUERY_MASK)
        return 0;
 
     return 1;
 }
 
+/**
+ * Set a statistic file for the query statistics.
+ *
+ * @param context A hx509 context.
+ * @param fn statistics file name
+ *
+ * @ingroup hx509_cert
+ */
+
 void
 hx509_query_statistic_file(hx509_context context, const char *fn)
 {
@@ -2362,6 +2965,16 @@ stat_sort(const void *a, const void *b)
     return be->stats - ae->stats;
 }
 
+/**
+ * Unparse the statistics file and print the result on a FILE descriptor.
+ *
+ * @param context A hx509 context.
+ * @param printtype tyep to print
+ * @param out the FILE to write the data on.
+ *
+ * @ingroup hx509_cert
+ */
+
 void
 hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
 {
@@ -2435,6 +3048,20 @@ hx509_query_unparse_stats(hx509_context context, int printtype, FILE *out)
            multiqueries, totalqueries);
 }
 
+/**
+ * Check the extended key usage on the hx509 certificate.
+ *
+ * @param context A hx509 context.
+ * @param cert A hx509 context.
+ * @param eku the EKU to check for
+ * @param allow_any_eku if the any EKU is set, allow that to be a
+ * substitute.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_check_eku(hx509_context context, hx509_cert cert,
                     const heim_oid *eku, int allow_any_eku)
@@ -2511,6 +3138,19 @@ _hx509_cert_get_eku(hx509_context context,
     return 0;
 }
 
+/**
+ * Encodes the hx509 certificate as a DER encode binary.
+ *
+ * @param context A hx509 context.
+ * @param c the certificate to encode.
+ * @param os the encode certificate, set to NULL, 0 on case of
+ * error. Free the returned structure with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_cert
+ */
+
 int
 hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
 {
@@ -2522,8 +3162,11 @@ hx509_cert_binary(hx509_context context, hx509_cert c, heim_octet_string *os)
 
     ASN1_MALLOC_ENCODE(Certificate, os->data, os->length, 
                       _hx509_get_cert(c), &size, ret);
-    if (ret)
+    if (ret) {
+       os->data = NULL;
+       os->length = 0;
        return ret;
+    }
     if (os->length != size)
        _hx509_abort("internal ASN.1 encoder error");
 
@@ -2550,3 +3193,16 @@ _hx509_abort(const char *fmt, ...)
     abort();
 }
 
+/**
+ * Free a data element allocated in the library.
+ *
+ * @param ptr data to be freed.
+ *
+ * @ingroup hx509_misc
+ */
+
+void
+hx509_xfree(void *ptr)
+{
+    free(ptr);
+}
index 30f364060d0b5ef14096304650575661962940da..80bcaac6c9832b54e46d9e7db6418adfd60ebd1e 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: cms.c 21319 2007-06-25 19:46:52Z lha $");
+RCSID("$Id: cms.c 22327 2007-12-15 04:49:37Z lha $");
+
+/**
+ * @page page_cms CMS/PKCS7 message functions.
+ *
+ * CMS is defined in RFC 3369 and is an continuation of the RSA Labs
+ * standard PKCS7. The basic messages in CMS is 
+ *
+ * - SignedData
+ *   Data signed with private key (RSA, DSA, ECDSA) or secret
+ *   (symmetric) key
+ * - EnvelopedData
+ *   Data encrypted with private key (RSA)
+ * - EncryptedData
+ *   Data encrypted with secret (symmetric) key.
+ * - ContentInfo
+ *   Wrapper structure including type and data.
+ *
+ *
+ * See the library functions here: @ref hx509_cms
+ */
 
 #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X)))
 #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0)
 
+/**
+ * Wrap data and oid in a ContentInfo and encode it.
+ *
+ * @param oid type of the content.
+ * @param buf data to be wrapped. If a NULL pointer is passed in, the
+ * optional content field in the ContentInfo is not going be filled
+ * in.
+ * @param res the encoded buffer, the result should be freed with
+ * der_free_octet_string().
+ *
+ * @return Returns an hx509 error code.
+ * 
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_wrap_ContentInfo(const heim_oid *oid,
                           const heim_octet_string *buf,
@@ -52,18 +87,20 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
     ret = der_copy_oid(oid, &ci.contentType);
     if (ret)
        return ret;
-    ALLOC(ci.content, 1);
-    if (ci.content == NULL) {
-       free_ContentInfo(&ci);
-       return ENOMEM;
-    }
-    ci.content->data = malloc(buf->length);
-    if (ci.content->data == NULL) {
-       free_ContentInfo(&ci);
-       return ENOMEM;
+    if (buf) {
+       ALLOC(ci.content, 1);
+       if (ci.content == NULL) {
+           free_ContentInfo(&ci);
+           return ENOMEM;
+       }
+       ci.content->data = malloc(buf->length);
+       if (ci.content->data == NULL) {
+           free_ContentInfo(&ci);
+           return ENOMEM;
+       }
+       memcpy(ci.content->data, buf->data, buf->length);
+       ci.content->length = buf->length;
     }
-    memcpy(ci.content->data, buf->data, buf->length);
-    ci.content->length = buf->length;
 
     ASN1_MALLOC_ENCODE(ContentInfo, res->data, res->length, &ci, &size, ret);
     free_ContentInfo(&ci);
@@ -75,6 +112,20 @@ hx509_cms_wrap_ContentInfo(const heim_oid *oid,
     return 0;
 }
 
+/**
+ * Decode an ContentInfo and unwrap data and oid it.
+ *
+ * @param in the encoded buffer.
+ * @param oid type of the content.
+ * @param out data to be wrapped.
+ * @param have_data since the data is optional, this flags show dthe
+ * diffrence between no data and the zero length data.
+ *
+ * @return Returns an hx509 error code.
+ * 
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_unwrap_ContentInfo(const heim_octet_string *in,
                             heim_oid *oid,
@@ -267,6 +318,27 @@ find_CMSIdentifier(hx509_context context,
     return 0;
 }
 
+/**
+ * Decode and unencrypt EnvelopedData.
+ *
+ * Extract data and parameteres from from the EnvelopedData. Also
+ * supports using detached EnvelopedData.
+ *
+ * @param context A hx509 context.
+ * @param certs Certificate that can decrypt the EnvelopedData
+ * encryption key.
+ * @param flags HX509_CMS_UE flags to control the behavior.
+ * @param data pointer the structure the contains the DER/BER encoded
+ * EnvelopedData stucture.
+ * @param length length of the data that data point to.
+ * @param encryptedContent in case of detached signature, this
+ * contains the actual encrypted data, othersize its should be NULL.
+ * @param contentType output type oid, should be freed with der_free_oid().
+ * @param content the data, free with der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_unenvelope(hx509_context context,
                     hx509_certs certs,
@@ -335,11 +407,6 @@ hx509_cms_unenvelope(hx509_context context,
 
        ri = &ed.recipientInfos.val[i];
 
-       /* ret = search_keyset(ri,
-        *      PRIVATE_KEY,
-        *      ki->keyEncryptionAlgorithm.algorithm);
-        */
-
        ret = find_CMSIdentifier(context, &ri->rid, certs, &cert,
                                 HX509_QUERY_PRIVATE_KEY|findflags);
        if (ret)
@@ -444,6 +511,29 @@ out:
     return ret;
 }
 
+/**
+ * Encrypt end encode EnvelopedData.
+ *
+ * Encrypt and encode EnvelopedData. The data is encrypted with a
+ * random key and the the random key is encrypted with the
+ * certificates private key. This limits what private key type can be
+ * used to RSA.
+ *
+ * @param context A hx509 context.
+ * @param flags flags to control the behavior, no flags today
+ * @param cert Certificate to encrypt the EnvelopedData encryption key
+ * with.
+ * @param data pointer the data to encrypt.
+ * @param length length of the data that data point to.
+ * @param encryption_type Encryption cipher to use for the bulk data,
+ * use NULL to get default.
+ * @param contentType type of the data that is encrypted
+ * @param content the output of the function,
+ * free with der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_envelope_1(hx509_context context,
                     int flags,
@@ -637,13 +727,31 @@ find_attribute(const CMSAttributes *attr, const heim_oid *oid)
     return NULL;
 }
 
+/**
+ * Decode SignedData and verify that the signature is correct.
+ *
+ * @param context A hx509 context.
+ * @param ctx a hx509 version context
+ * @param data
+ * @param length length of the data that data point to.
+ * @param signedContent
+ * @param pool certificate pool to build certificates paths.
+ * @param contentType free with der_free_oid()
+ * @param content the output of the function, free with
+ * der_free_octet_string().
+ * @param signer_certs list of the cerficates used to sign this
+ * request, free with hx509_certs_free().
+ *
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_verify_signed(hx509_context context,
                        hx509_verify_ctx ctx,
                        const void *data,
                        size_t length,
                        const heim_octet_string *signedContent,
-                       hx509_certs store,
+                       hx509_certs pool,
                        heim_oid *contentType,
                        heim_octet_string *content,
                        hx509_certs *signer_certs)
@@ -701,8 +809,8 @@ hx509_cms_verify_signed(hx509_context context,
     if (ret)
        goto out;
 
-    if (store) {
-       ret = hx509_certs_merge(context, certs, store);
+    if (pool) {
+       ret = hx509_certs_merge(context, certs, pool);
        if (ret)
            goto out;
     }
@@ -946,6 +1054,29 @@ add_one_attribute(Attribute **attr,
     return 0;
 }
        
+/**
+ * Decode SignedData and verify that the signature is correct.
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * @param eContentType the type of the data.
+ * @param data data to sign
+ * @param length length of the data that data point to.
+ * @param digest_alg digest algorithm to use, use NULL to get the
+ * default or the peer determined algorithm.
+ * @param cert certificate to use for sign the data.
+ * @param peer info about the peer the message to send the message to,
+ * like what digest algorithm to use.
+ * @param anchors trust anchors that the client will use, used to
+ * polulate the certificates included in the message
+ * @param pool certificates to use in try to build the path to the
+ * trust anchors.
+ * @param signed_data the output of the function, free with
+ * der_free_octet_string().
+ *
+ * @ingroup hx509_cms
+ */
+
 int
 hx509_cms_create_signed_1(hx509_context context,
                          int flags,
@@ -1050,7 +1181,7 @@ hx509_cms_create_signed_1(hx509_context context,
     }
 
     /*
-     * If its not pkcs7-data send signedAttributes
+     * If it isn't pkcs7-data send signedAttributes
      */
 
     if (der_heim_oid_cmp(eContentType, oid_id_pkcs7_data()) != 0) {
index d86300bd586ce9071ef5f1827eeab6303af41ef6..e0f00ad7b45bd74dc66cc0728e31f633218093d7 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: crypto.c 21318 2007-06-25 19:46:32Z lha $");
+RCSID("$Id: crypto.c 22435 2008-01-14 20:53:56Z lha $");
 
 struct hx509_crypto;
 
@@ -64,6 +64,7 @@ struct hx509_private_key_ops {
     int (*generate_private_key)(hx509_context,
                                struct hx509_generate_private_context *,
                                hx509_private_key);
+    BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
     int (*handle_alg)(const hx509_private_key,
                      const AlgorithmIdentifier *,
                      enum crypto_op_type);
@@ -115,6 +116,9 @@ struct signature_alg {
 #define SIG_PUBLIC_SIG 0x200
 #define SIG_SECRET     0x400
 
+#define RA_RSA_USES_DIGEST_INFO 0x1000000
+
+
     int (*verify_signature)(hx509_context context,
                            const struct signature_alg *,
                            const Certificate *,
@@ -248,43 +252,57 @@ rsa_verify_signature(hx509_context context,
     }
     if (retsize > tosize)
        _hx509_abort("internal rsa decryption failure: ret > tosize");
-    ret = decode_DigestInfo(to, retsize, &di, &size);
-    free(to);
-    if (ret) {
-       goto out;
-    }
 
-    /* Check for extra data inside the sigature */
-    if (size != retsize) {
-       ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
-       hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
-       goto out;
-    }
+    if (sig_alg->flags & RA_RSA_USES_DIGEST_INFO) {
 
-    if (sig_alg->digest_oid &&
-       der_heim_oid_cmp(&di.digestAlgorithm.algorithm, 
-                    (*sig_alg->digest_oid)()) != 0) 
-    {
-       ret = HX509_CRYPTO_OID_MISMATCH;
-       hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
-       goto out;
-    }
+       ret = decode_DigestInfo(to, retsize, &di, &size);
+       free(to);
+       if (ret) {
+           goto out;
+       }
+       
+       /* Check for extra data inside the sigature */
+       if (size != retsize) {
+           ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+           hx509_set_error_string(context, 0, ret, "size from decryption mismatch");
+           goto out;
+       }
+       
+       if (sig_alg->digest_oid &&
+           der_heim_oid_cmp(&di.digestAlgorithm.algorithm, 
+                            (*sig_alg->digest_oid)()) != 0) 
+       {
+           ret = HX509_CRYPTO_OID_MISMATCH;
+           hx509_set_error_string(context, 0, ret, "object identifier in RSA sig mismatch");
+           goto out;
+       }
+       
+       /* verify that the parameters are NULL or the NULL-type */
+       if (di.digestAlgorithm.parameters != NULL &&
+           (di.digestAlgorithm.parameters->length != 2 ||
+            memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
+       {
+           ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+           hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
+           goto out;
+       }
 
-    /* verify that the parameters are NULL or the NULL-type */
-    if (di.digestAlgorithm.parameters != NULL &&
-       (di.digestAlgorithm.parameters->length != 2 ||
-        memcmp(di.digestAlgorithm.parameters->data, "\x05\x00", 2) != 0))
-    {
-       ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
-       hx509_set_error_string(context, 0, ret, "Extra parameters inside RSA signature");
-       goto out;
+       ret = _hx509_verify_signature(context,
+                                     NULL,
+                                     &di.digestAlgorithm,
+                                     data,
+                                     &di.digest);
+    } else {
+       if (retsize != data->length ||
+           memcmp(to, data->data, retsize) != 0)
+       {
+           ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+           hx509_set_error_string(context, 0, ret, "RSA Signature incorrect");
+           goto out;
+       }
+       free(to);
     }
 
-    ret = _hx509_verify_signature(context,
-                                 NULL,
-                                 &di.digestAlgorithm,
-                                 data,
-                                 &di.digest);
  out:
     free_DigestInfo(&di);
     RSA_free(rsa);
@@ -303,7 +321,6 @@ rsa_create_signature(hx509_context context,
     const AlgorithmIdentifier *digest_alg;
     heim_octet_string indata;
     const heim_oid *sig_oid;
-    DigestInfo di;
     size_t size;
     int ret;
     
@@ -324,6 +341,8 @@ rsa_create_signature(hx509_context context,
        digest_alg = hx509_signature_sha1();
     } else if (der_heim_oid_cmp(sig_oid, oid_id_pkcs1_rsaEncryption()) == 0) {
        digest_alg = hx509_signature_sha1();
+    } else if (der_heim_oid_cmp(sig_oid, oid_id_heim_rsa_pkcs1_x509()) == 0) {
+       digest_alg = NULL;
     } else
        return HX509_ALG_NOT_SUPP;
 
@@ -335,29 +354,34 @@ rsa_create_signature(hx509_context context,
        }
     }
 
-    memset(&di, 0, sizeof(di));
+    if (digest_alg) {
+       DigestInfo di;
+       memset(&di, 0, sizeof(di));
 
-    ret = _hx509_create_signature(context,
-                                 NULL,
-                                 digest_alg,
-                                 data,
-                                 &di.digestAlgorithm,
-                                 &di.digest);
-    if (ret)
-       return ret;
-    ASN1_MALLOC_ENCODE(DigestInfo,
-                      indata.data,
-                      indata.length,
-                      &di,
-                      &size,
-                      ret);
-    free_DigestInfo(&di);
-    if (ret) {
-       hx509_set_error_string(context, 0, ret, "out of memory");
-       return ret;
+       ret = _hx509_create_signature(context,
+                                     NULL,
+                                     digest_alg,
+                                     data,
+                                     &di.digestAlgorithm,
+                                     &di.digest);
+       if (ret)
+           return ret;
+       ASN1_MALLOC_ENCODE(DigestInfo,
+                          indata.data,
+                          indata.length,
+                          &di,
+                          &size,
+                          ret);
+       free_DigestInfo(&di);
+       if (ret) {
+           hx509_set_error_string(context, 0, ret, "out of memory");
+           return ret;
+       }
+       if (indata.length != size)
+           _hx509_abort("internal ASN.1 encoder error");
+    } else {
+       indata = *data;
     }
-    if (indata.length != size)
-       _hx509_abort("internal ASN.1 encoder error");
 
     sig->length = RSA_size(signer->private_key.rsa);
     sig->data = malloc(sig->length);
@@ -371,7 +395,8 @@ rsa_create_signature(hx509_context context,
                              sig->data, 
                              signer->private_key.rsa,
                              RSA_PKCS1_PADDING);
-    der_free_octet_string(&indata);
+    if (indata.data != data->data)
+       der_free_octet_string(&indata);
     if (ret <= 0) {
        ret = HX509_CMS_FAILED_CREATE_SIGATURE;
        hx509_set_error_string(context, 0, ret,
@@ -517,6 +542,18 @@ rsa_private_key_export(hx509_context context,
     return 0;
 }
 
+static BIGNUM *
+rsa_get_internal(hx509_context context, hx509_private_key key, const char *type)
+{
+    if (strcasecmp(type, "rsa-modulus") == 0) {
+       return BN_dup(key->private_key.rsa->n);
+    } else if (strcasecmp(type, "rsa-exponent") == 0) {
+       return BN_dup(key->private_key.rsa->e);
+    } else
+       return NULL;
+}
+
+
 
 static hx509_private_key_ops rsa_private_key_ops = {
     "RSA PRIVATE KEY",
@@ -524,7 +561,8 @@ static hx509_private_key_ops rsa_private_key_ops = {
     rsa_private_key2SPKI,
     rsa_private_key_export,
     rsa_private_key_import,
-    rsa_generate_private_key
+    rsa_generate_private_key,
+    rsa_get_internal
 };
 
 
@@ -833,13 +871,24 @@ md2_verify_signature(hx509_context context,
     return 0;
 }
 
+static const struct signature_alg heim_rsa_pkcs1_x509 = {
+    "rsa-pkcs1-x509",
+    oid_id_heim_rsa_pkcs1_x509,
+    hx509_signature_rsa_pkcs1_x509,
+    oid_id_pkcs1_rsaEncryption,
+    NULL,
+    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    rsa_verify_signature,
+    rsa_create_signature
+};
+
 static const struct signature_alg pkcs1_rsa_sha1_alg = {
     "rsa",
     oid_id_pkcs1_rsaEncryption,
     hx509_signature_rsa_with_sha1,
     oid_id_pkcs1_rsaEncryption,
     NULL,
-    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     rsa_verify_signature,
     rsa_create_signature
 };
@@ -850,7 +899,7 @@ static const struct signature_alg rsa_with_sha256_alg = {
     hx509_signature_rsa_with_sha256,
     oid_id_pkcs1_rsaEncryption,
     oid_id_sha256,
-    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     rsa_verify_signature,
     rsa_create_signature
 };
@@ -861,7 +910,7 @@ static const struct signature_alg rsa_with_sha1_alg = {
     hx509_signature_rsa_with_sha1,
     oid_id_pkcs1_rsaEncryption,
     oid_id_secsig_sha_1,
-    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     rsa_verify_signature,
     rsa_create_signature
 };
@@ -872,7 +921,7 @@ static const struct signature_alg rsa_with_md5_alg = {
     hx509_signature_rsa_with_md5,
     oid_id_pkcs1_rsaEncryption,
     oid_id_rsa_digest_md5,
-    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     rsa_verify_signature,
     rsa_create_signature
 };
@@ -883,7 +932,7 @@ static const struct signature_alg rsa_with_md2_alg = {
     hx509_signature_rsa_with_md2,
     oid_id_pkcs1_rsaEncryption,
     oid_id_rsa_digest_md2,
-    PROVIDE_CONF|REQUIRE_SIGNER|SIG_PUBLIC_SIG,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG,
     rsa_verify_signature,
     rsa_create_signature
 };
@@ -952,7 +1001,7 @@ static const struct signature_alg *sig_algs[] = {
     &pkcs1_rsa_sha1_alg,
     &rsa_with_md5_alg,
     &rsa_with_md2_alg,
-    &pkcs1_rsa_sha1_alg,
+    &heim_rsa_pkcs1_x509,
     &dsa_sha1_alg,
     &sha256_alg,
     &sha1_alg,
@@ -1423,6 +1472,11 @@ const AlgorithmIdentifier _hx509_signature_rsa_data = {
     { 7, rk_UNCONST(rsa_oid) }, NULL
 };
 
+static const unsigned rsa_pkcs1_x509_oid[] ={ 1, 2, 752, 43, 16, 1 };
+const AlgorithmIdentifier _hx509_signature_rsa_pkcs1_x509_data = { 
+    { 6, rk_UNCONST(rsa_pkcs1_x509_oid) }, NULL
+};
+
 static const unsigned des_rsdi_ede3_cbc_oid[] ={ 1, 2, 840, 113549, 3, 7 };
 const AlgorithmIdentifier _hx509_des_rsdi_ede3_cbc_oid = {
     { 6, rk_UNCONST(des_rsdi_ede3_cbc_oid) }, NULL
@@ -1490,6 +1544,10 @@ const AlgorithmIdentifier *
 hx509_signature_rsa(void)
 { return &_hx509_signature_rsa_data; }
 
+const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509(void)
+{ return &_hx509_signature_rsa_pkcs1_x509_data; }
+
 const AlgorithmIdentifier *
 hx509_crypto_des_rsdi_ede3_cbc(void)
 { return &_hx509_des_rsdi_ede3_cbc_oid; }
@@ -1597,6 +1655,16 @@ _hx509_private_key_exportable(hx509_private_key key)
     return 1;
 }
 
+BIGNUM *
+_hx509_private_key_get_internal(hx509_context context,
+                               hx509_private_key key, 
+                               const char *type)
+{
+    if (key->ops->get_internal == NULL)
+       return NULL;
+    return (*key->ops->get_internal)(context, key, type);
+}
+
 int 
 _hx509_private_key_export(hx509_context context,
                          const hx509_private_key key,
index 4cb2f9f4b177ef46e55e7f5424bcd3f678b1c271..f868c22488cb4d333909d45b0a302bb90af7c1db 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: env.c 19878 2007-01-13 00:58:39Z lha $");
+RCSID("$Id: env.c 22349 2007-12-26 19:32:49Z lha $");
+
+/**
+ * @page page_env Hx509 enviroment functions
+ *
+ * See the library functions here: @ref hx509_env
+ */
 
 struct hx509_env {
     struct {
@@ -42,6 +48,17 @@ struct hx509_env {
     size_t len;
 };
 
+/**
+ * Allocate a new hx509_env container object.
+ *
+ * @param context A hx509 context.
+ * @param env return a hx509_env structure, free with hx509_env_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_env
+ */
+
 int
 hx509_env_init(hx509_context context, hx509_env *env)
 {
@@ -53,6 +70,19 @@ hx509_env_init(hx509_context context, hx509_env *env)
     return 0;
 }
 
+/**
+ * Add a new key/value pair to the hx509_env.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to add
+ * @param value value to add
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_env
+ */
+
 int
 hx509_env_add(hx509_context context, hx509_env env, 
              const char *key, const char *value)
@@ -80,6 +110,19 @@ hx509_env_add(hx509_context context, hx509_env env,
     return 0;
 }
 
+/**
+ * Search the hx509_env for a key.
+ *
+ * @param context A hx509 context.
+ * @param env enviroment to add the enviroment variable too.
+ * @param key key to search for.
+ * @param len length of key.
+ *
+ * @return the value if the key is found, NULL otherwise.
+ *
+ * @ingroup hx509_env
+ */
+
 const char *
 hx509_env_lfind(hx509_context context, hx509_env env,
                const char *key, size_t len)
@@ -94,6 +137,13 @@ hx509_env_lfind(hx509_context context, hx509_env env,
     return NULL;
 }
 
+/**
+ * Free an hx509_env enviroment context.
+ *
+ * @param env the enviroment to free.
+ *
+ * @ingroup hx509_env
+ */
 
 void
 hx509_env_free(hx509_env *env)
index 9f3a01487323dea974c486b24a02ceacbabf694e..25119ed28830626f879fd519beff742502085931 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: error.c 20912 2007-06-05 03:53:52Z lha $");
+RCSID("$Id: error.c 22332 2007-12-17 01:03:22Z lha $");
+
+/**
+ * @page page_error Hx509 error reporting functions
+ *
+ * See the library functions here: @ref hx509_error
+ */
 
 struct hx509_error_data {
     hx509_error next;
@@ -51,6 +57,14 @@ free_error_string(hx509_error msg)
     }
 }
 
+/**
+ * Resets the error strings the hx509 context.
+ *
+ * @param context A hx509 context.
+ *
+ * @ingroup hx509_error
+ */
+
 void
 hx509_clear_error_string(hx509_context context)
 {
@@ -58,6 +72,20 @@ hx509_clear_error_string(hx509_context context)
     context->error = NULL;
 }
 
+/**
+ * Add an error message to the hx509 context.
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * - HX509_ERROR_APPEND appends the error string to the old messages
+     (code is updated).
+ * @param code error code related to error message
+ * @param fmt error message format
+ * @param ap arguments to error message format
+ *
+ * @ingroup hx509_error
+ */
+
 void
 hx509_set_error_stringv(hx509_context context, int flags, int code, 
                        const char *fmt, va_list ap)
@@ -86,6 +114,20 @@ hx509_set_error_stringv(hx509_context context, int flags, int code,
     }
 }
 
+/**
+ * See hx509_set_error_stringv(). 
+ *
+ * @param context A hx509 context.
+ * @param flags
+ * - HX509_ERROR_APPEND appends the error string to the old messages
+     (code is updated).
+ * @param code error code related to error message
+ * @param fmt error message format
+ * @param ... arguments to error message format
+ *
+ * @ingroup hx509_error
+ */
+
 void
 hx509_set_error_string(hx509_context context, int flags, int code,
                       const char *fmt, ...)
@@ -97,6 +139,17 @@ hx509_set_error_string(hx509_context context, int flags, int code,
     va_end(ap);
 }
 
+/**
+ * Get an error string from context associated with error_code.
+ *
+ * @param context A hx509 context.
+ * @param error_code Get error message for this error code.
+ *
+ * @return error string, free with hx509_free_error_string().
+ *
+ * @ingroup hx509_error
+ */
+
 char *
 hx509_get_error_string(hx509_context context, int error_code)
 {
@@ -125,6 +178,32 @@ hx509_get_error_string(hx509_context context, int error_code)
     return rk_strpoolcollect(p);
 }
 
+/**
+ * Free error string returned by hx509_get_error_string().
+ *
+ * @param str error string to free.
+ *
+ * @ingroup hx509_error
+ */
+
+void
+hx509_free_error_string(char *str)
+{
+    free(str);
+}
+
+/**
+ * Print error message and fatally exit from error code
+ *
+ * @param context A hx509 context.
+ * @param exit_code exit() code from process.
+ * @param error_code Error code for the reason to exit.
+ * @param fmt format string with the exit message.
+ * @param ... argument to format string.
+ *
+ * @ingroup hx509_error
+ */
+
 void
 hx509_err(hx509_context context, int exit_code, 
          int error_code, const char *fmt, ...)
index acbc3218c649a7250cb00fa72c0b2481c450e47b..be36c07421e7092506ba0bdb8766ddbe75f69f2b 100644 (file)
@@ -8,6 +8,11 @@
 #define __attribute__(x)
 #endif
 
+int
+_hx509_AlgorithmIdentifier_cmp (
+       const AlgorithmIdentifier */*p*/,
+       const AlgorithmIdentifier */*q*/);
+
 int
 _hx509_Certificate_cmp (
        const Certificate */*p*/,
@@ -269,12 +274,14 @@ _hx509_match_keys (
 int
 _hx509_name_cmp (
        const Name */*n1*/,
-       const Name */*n2*/);
+       const Name */*n2*/,
+       int */*c*/);
 
 int
 _hx509_name_ds_cmp (
        const DirectoryString */*ds1*/,
-       const DirectoryString */*ds2*/);
+       const DirectoryString */*ds2*/,
+       int */*diff*/);
 
 int
 _hx509_name_from_Name (
@@ -314,6 +321,14 @@ _hx509_pbe_decrypt (
        const heim_octet_string */*econtent*/,
        heim_octet_string */*content*/);
 
+int
+_hx509_pbe_encrypt (
+       hx509_context /*context*/,
+       hx509_lock /*lock*/,
+       const AlgorithmIdentifier */*ai*/,
+       const heim_octet_string */*content*/,
+       heim_octet_string */*econtent*/);
+
 void
 _hx509_pi_printf (
        int (*/*func*/)(void *, const char *),
@@ -344,6 +359,12 @@ _hx509_private_key_exportable (hx509_private_key /*key*/);
 int
 _hx509_private_key_free (hx509_private_key */*key*/);
 
+BIGNUM *
+_hx509_private_key_get_internal (
+       hx509_context /*context*/,
+       hx509_private_key /*key*/,
+       const char */*type*/);
+
 int
 _hx509_private_key_init (
        hx509_private_key */*key*/,
@@ -414,11 +435,35 @@ _hx509_request_add_email (
 void
 _hx509_request_free (hx509_request */*req*/);
 
+int
+_hx509_request_get_SubjectPublicKeyInfo (
+       hx509_context /*context*/,
+       hx509_request /*req*/,
+       SubjectPublicKeyInfo */*key*/);
+
+int
+_hx509_request_get_name (
+       hx509_context /*context*/,
+       hx509_request /*req*/,
+       hx509_name */*name*/);
+
 int
 _hx509_request_init (
        hx509_context /*context*/,
        hx509_request */*req*/);
 
+int
+_hx509_request_parse (
+       hx509_context /*context*/,
+       const char */*path*/,
+       hx509_request */*req*/);
+
+int
+_hx509_request_print (
+       hx509_context /*context*/,
+       hx509_request /*req*/,
+       FILE */*f*/);
+
 int
 _hx509_request_set_SubjectPublicKeyInfo (
        hx509_context /*context*/,
@@ -438,6 +483,9 @@ _hx509_request_to_pkcs10 (
        const hx509_private_key /*signer*/,
        heim_octet_string */*request*/);
 
+hx509_revoke_ctx
+_hx509_revoke_ref (hx509_revoke_ctx /*ctx*/);
+
 int
 _hx509_set_cert_attribute (
        hx509_context /*context*/,
index 71fb29d59dd042759ce5d1ff20940aa9fb85bc67..3e297424cc9ce0b56c8d2628b20fdaa649dddb8d 100644 (file)
@@ -183,6 +183,7 @@ hx509_cert_cmp (
 
 int
 hx509_cert_find_subjectAltName_otherName (
+       hx509_context /*context*/,
        hx509_cert /*cert*/,
        const heim_oid */*oid*/,
        hx509_octet_string_list */*list*/);
@@ -192,9 +193,16 @@ hx509_cert_free (hx509_cert /*cert*/);
 
 int
 hx509_cert_get_SPKI (
+       hx509_context /*context*/,
        hx509_cert /*p*/,
        SubjectPublicKeyInfo */*spki*/);
 
+int
+hx509_cert_get_SPKI_AlgorithmIdentifier (
+       hx509_context /*context*/,
+       hx509_cert /*p*/,
+       AlgorithmIdentifier */*alg*/);
+
 hx509_cert_attribute
 hx509_cert_get_attribute (
        hx509_cert /*cert*/,
@@ -230,6 +238,9 @@ hx509_cert_get_subject (
        hx509_cert /*p*/,
        hx509_name */*name*/);
 
+int
+hx509_cert_have_private_key (hx509_cert /*p*/);
+
 int
 hx509_cert_init (
        hx509_context /*context*/,
@@ -305,7 +316,7 @@ int
 hx509_certs_iter (
        hx509_context /*context*/,
        hx509_certs /*certs*/,
-       int (*/*fn*/)(hx509_context, void *, hx509_cert),
+       int (*/*func*/)(hx509_context, void *, hx509_cert),
        void */*ctx*/);
 
 int
@@ -402,7 +413,7 @@ hx509_cms_verify_signed (
        const void */*data*/,
        size_t /*length*/,
        const heim_octet_string */*signedContent*/,
-       hx509_certs /*store*/,
+       hx509_certs /*pool*/,
        heim_oid */*contentType*/,
        heim_octet_string */*content*/,
        hx509_certs */*signer_certs*/);
@@ -580,6 +591,9 @@ hx509_err (
        const char */*fmt*/,
        ...);
 
+void
+hx509_free_error_string (char */*str*/);
+
 void
 hx509_free_octet_string_list (hx509_octet_string_list */*list*/);
 
@@ -651,6 +665,11 @@ hx509_lock_set_prompter (
        hx509_prompter_fct /*prompt*/,
        void */*data*/);
 
+int
+hx509_name_binary (
+       const hx509_name /*name*/,
+       heim_octet_string */*os*/);
+
 int
 hx509_name_cmp (
        hx509_name /*n1*/,
@@ -684,12 +703,6 @@ hx509_name_to_Name (
        const hx509_name /*from*/,
        Name */*to*/);
 
-int
-hx509_name_to_der_name (
-       const hx509_name /*name*/,
-       void **/*data*/,
-       size_t */*length*/);
-
 int
 hx509_name_to_string (
        const hx509_name /*name*/,
@@ -782,13 +795,6 @@ hx509_pem_write (
        const void */*data*/,
        size_t /*size*/);
 
-void
-hx509_print_func (
-       hx509_vprint_func /*func*/,
-       void */*ctx*/,
-       const char */*fmt*/,
-       ...);
-
 void
 hx509_print_stdout (
        void */*ctx*/,
@@ -814,6 +820,11 @@ hx509_query_match_cmp_func (
        int (*/*func*/)(void *, hx509_cert),
        void */*ctx*/);
 
+int
+hx509_query_match_eku (
+       hx509_query */*q*/,
+       const heim_oid */*eku*/);
+
 int
 hx509_query_match_friendly_name (
        hx509_query */*q*/,
@@ -901,6 +912,9 @@ hx509_signature_md5 (void);
 const AlgorithmIdentifier *
 hx509_signature_rsa (void);
 
+const AlgorithmIdentifier *
+hx509_signature_rsa_pkcs1_x509 (void);
+
 const AlgorithmIdentifier *
 hx509_signature_rsa_with_md2 (void);
 
@@ -1030,6 +1044,9 @@ hx509_verify_signature (
        const heim_octet_string */*data*/,
        const heim_octet_string */*sig*/);
 
+void
+hx509_xfree (void */*ptr*/);
+
 #ifdef __cplusplus
 }
 #endif
index 2f22cedfbc831fc2bc343a14dc29318293fdf0ce..be02f6347490392294625102ccdca61959f1c81e 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: hx509.h 21310 2007-06-25 18:26:06Z lha $ */
+/* $Id: hx509.h 22464 2008-01-16 14:24:50Z lha $ */
 
 typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
 typedef struct hx509_cert_data *hx509_cert;
@@ -55,6 +55,10 @@ typedef struct hx509_crl *hx509_crl;
 
 typedef void (*hx509_vprint_func)(void *, const char *, va_list);
 
+enum {
+    HX509_VHN_F_ALLOW_NO_MATCH = 1
+};
+
 enum {
     HX509_VALIDATE_F_VALIDATE = 1,
     HX509_VALIDATE_F_VERBOSE = 2
@@ -107,6 +111,7 @@ typedef enum {
 
 /* flags to hx509_certs_init */
 #define HX509_CERTS_CREATE                             0x01
+#define HX509_CERTS_UNPROTECT_ALL                      0x02
 
 /* flags to hx509_set_error_string */
 #define HX509_ERROR_APPEND                             0x01
index 90f3b3d907db44264ecbae5b396197ed7264bea2..8fc5cb8f2f7e8433b9b621fd1c2acbc283bb2d49 100644 (file)
@@ -3,7 +3,7 @@
 #
 # This might look like a com_err file, but is not
 #
-id "$Id: hx509_err.et 20807 2007-06-03 03:11:20Z lha $"
+id "$Id: hx509_err.et 22329 2007-12-15 05:13:14Z lha $"
 
 error_table hx
 prefix HX509
@@ -72,7 +72,7 @@ prefix HX509
 error_code CRL_USED_BEFORE_TIME, "CRL used before it became valid"
 error_code CRL_USED_AFTER_TIME, "CRL used after it became invalid"
 error_code CRL_INVALID_FORMAT, "CRL have invalid format"
-error_code CRL_CERT_REVOKED, "Certificate is included in CRL"
+error_code CERT_REVOKED, "Certificate is revoked"
 error_code REVOKE_STATUS_MISSING, "No revoke status found for certificates"
 error_code CRL_UNKNOWN_EXTENSION, "Unknown extension"
 error_code REVOKE_WRONG_DATA, "Got wrong CRL/OCSP data from server"
index 145bfcc006d038c215b6cd74b8a54cf5742f3286..6d89167bfcb53bd33773ec30b3192f3a399238bd 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: hx_locl.h 21083 2007-06-13 02:11:19Z lha $ */
+/* $Id: hx_locl.h 22538 2008-01-27 13:05:47Z lha $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -128,7 +128,8 @@ struct hx509_query_data {
 #define HX509_QUERY_MATCH_FUNCTION             0x080000
 #define HX509_QUERY_MATCH_KEY_HASH_SHA1                0x100000
 #define HX509_QUERY_MATCH_TIME                 0x200000
-#define HX509_QUERY_MASK                       0x3fffff
+#define HX509_QUERY_MATCH_EKU                  0x400000
+#define HX509_QUERY_MASK                       0x7fffff
     Certificate *subject;
     Certificate *certificate;
     heim_integer *serial;
@@ -142,6 +143,7 @@ struct hx509_query_data {
     void *cmp_func_ctx;
     heim_octet_string *keyhash_sha1;
     time_t timenow;
+    heim_oid *eku;
 };
 
 struct hx509_keyset_ops {
index 7da5705a80295d989dcba2c565a8173811e8c06e..2fcff7b03b352f527c6c1059a106a56add5520d8 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: keyset.c 21140 2007-06-18 21:24:19Z lha $");
+RCSID("$Id: keyset.c 22466 2008-01-16 14:26:35Z lha $");
+
+/**
+ * @page page_keyset Certificate store operations
+ *
+ * Type of certificates store:
+ * - MEMORY
+ *   In memory based format. Doesnt support storing.
+ * - FILE 
+ *   FILE supports raw DER certicates and PEM certicates. When PEM is
+ *   used the file can contain may certificates and match private
+ *   keys. Support storing the certificates. DER format only supports
+ *   on certificate and no private key.
+ * - PEM-FILE
+ *   Same as FILE, defaulting to PEM encoded certificates.
+ * - PEM-FILE
+ *   Same as FILE, defaulting to DER encoded certificates.
+ * - PKCS11
+ * - PKCS12
+ * - DIR
+ * - KEYCHAIN
+ *   Apple Mac OS X KeyChain backed keychain object.
+ *
+ * See the library functions here: @ref hx509_keyset
+ */
 
 struct hx509_certs_data {
     int ref;
@@ -69,6 +93,22 @@ _hx509_ks_register(hx509_context context, struct hx509_keyset_ops *ops)
     context->ks_num_ops++;
 }
 
+/**
+ * Open or creates a new hx509 certificate store.
+ *
+ * @param context A hx509 context
+ * @param name name of the store, format is TYPE:type-specific-string,
+ * if NULL is used the MEMORY store is used.
+ * @param flags list of flags:
+ * - HX509_CERTS_CREATE create a new keystore of the specific TYPE.
+ * - HX509_CERTS_UNPROTECT_ALL fails if any private key failed to be extracted.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ * @param certs return pointer, free with hx509_certs_free().
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_init(hx509_context context,
                 const char *name, int flags,
@@ -125,6 +165,21 @@ hx509_certs_init(hx509_context context,
     return 0;
 }
 
+/**
+ * Write the certificate store to stable storage.
+ *
+ * @param context A hx509 context.
+ * @param certs a certificate store to store.
+ * @param flags currently unused, use 0.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ *
+ * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION if
+ * the certificate store doesn't support the store operation.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_store(hx509_context context,
                  hx509_certs certs,
@@ -132,11 +187,11 @@ hx509_certs_store(hx509_context context,
                  hx509_lock lock)
 {
     if (certs->ops->store == NULL) {
-       hx509_set_error_string(context, 0, EINVAL,
+       hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION,
                               "keystore if type %s doesn't support "
                               "store operation",
                               certs->ops->name);
-       return EINVAL;
+       return HX509_UNSUPPORTED_OPERATION;
     }
 
     return (*certs->ops->store)(context, certs, certs->ops_data, flags, lock);
@@ -146,6 +201,8 @@ hx509_certs_store(hx509_context context,
 hx509_certs
 _hx509_certs_ref(hx509_certs certs)
 {
+    if (certs == NULL)
+       return NULL;
     if (certs->ref <= 0)
        _hx509_abort("certs refcount <= 0");
     certs->ref++;
@@ -154,6 +211,14 @@ _hx509_certs_ref(hx509_certs certs)
     return certs;
 }
 
+/**
+ * Free a certificate store.
+ *
+ * @param certs certificate store to free.
+ *
+ * @ingroup hx509_keyset
+ */
+
 void
 hx509_certs_free(hx509_certs *certs)
 {
@@ -169,6 +234,21 @@ hx509_certs_free(hx509_certs *certs)
     }
 }
 
+/**
+ * Start the integration
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over
+ * @param cursor cursor that will keep track of progress, free with
+ * hx509_certs_end_seq().
+ *
+ * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION is
+ * returned if the certificate store doesn't support the iteration
+ * operation.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_start_seq(hx509_context context,
                      hx509_certs certs,
@@ -177,10 +257,10 @@ hx509_certs_start_seq(hx509_context context,
     int ret;
 
     if (certs->ops->iter_start == NULL) {
-       hx509_set_error_string(context, 0, ENOENT
+       hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION
                               "Keyset type %s doesn't support iteration", 
                               certs->ops->name);
-       return ENOENT;
+       return HX509_UNSUPPORTED_OPERATION;
     }
 
     ret = (*certs->ops->iter_start)(context, certs, certs->ops_data, cursor);
@@ -190,6 +270,21 @@ hx509_certs_start_seq(hx509_context context,
     return 0;
 }
 
+/**
+ * Get next ceritificate from the certificate keystore pointed out by
+ * cursor.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param cursor cursor that keeps track of progress.
+ * @param cert return certificate next in store, NULL if the store
+ * contains no more certificates. Free with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_next_cert(hx509_context context,
                      hx509_certs certs,
@@ -200,6 +295,18 @@ hx509_certs_next_cert(hx509_context context,
     return (*certs->ops->iter)(context, certs, certs->ops_data, cursor, cert);
 }
 
+/**
+ * End the iteration over certificates.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param cursor cursor that will keep track of progress, freed.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_end_seq(hx509_context context,
                    hx509_certs certs,
@@ -209,11 +316,26 @@ hx509_certs_end_seq(hx509_context context,
     return 0;
 }
 
+/**
+ * Iterate over all certificates in a keystore and call an function
+ * for each fo them.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to iterate over.
+ * @param func function to call for each certificate. The function
+ * should return non-zero to abort the iteration, that value is passed
+ * back to te caller of hx509_certs_iter().
+ * @param ctx context variable that will passed to the function.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
 
 int
 hx509_certs_iter(hx509_context context, 
                 hx509_certs certs, 
-                int (*fn)(hx509_context, void *, hx509_cert),
+                int (*func)(hx509_context, void *, hx509_cert),
                 void *ctx)
 {
     hx509_cursor cursor;
@@ -232,7 +354,7 @@ hx509_certs_iter(hx509_context context,
            ret = 0;
            break;
        }
-       ret = (*fn)(context, ctx, c);
+       ret = (*func)(context, ctx, c);
        hx509_cert_free(c);
        if (ret)
            break;
@@ -243,6 +365,20 @@ hx509_certs_iter(hx509_context context,
     return ret;
 }
 
+
+/**
+ * Function to use to hx509_certs_iter() as a function argument, the
+ * ctx variable to hx509_certs_iter() should be a FILE file descriptor.
+ *
+ * @param context a hx509 context.
+ * @param ctx used by hx509_certs_iter().
+ * @param c a certificate
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_ci_print_names(hx509_context context, void *ctx, hx509_cert c)
 {
@@ -264,10 +400,20 @@ hx509_ci_print_names(hx509_context context, void *ctx, hx509_cert c)
     return 0;
 }
 
-/*
- * The receiving keyset `certs´ will either increase reference counter
- * of the `cert´ or make a deep copy, either way, the caller needs to
- * free the `cert´ itself.
+/**
+ * Add a certificate to the certificiate store.
+ *
+ * The receiving keyset certs will either increase reference counter
+ * of the cert or make a deep copy, either way, the caller needs to
+ * free the cert itself.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to add the certificate to.
+ * @param cert certificate to add.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
  */
 
 int
@@ -283,6 +429,20 @@ hx509_certs_add(hx509_context context, hx509_certs certs, hx509_cert cert)
     return (*certs->ops->add)(context, certs, certs->ops_data, cert);
 }
 
+/**
+ * Find a certificate matching the query.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to search.
+ * @param q query allocated with @ref hx509_query functions.
+ * @param r return certificate (or NULL on error), should be freed
+ * with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_find(hx509_context context,
                 hx509_certs certs, 
@@ -335,6 +495,19 @@ certs_merge_func(hx509_context context, void *ctx, hx509_cert c)
     return hx509_certs_add(context, (hx509_certs)ctx, c);
 }
 
+/**
+ * Merge a certificate store into another. The from store is keep
+ * intact.
+ *
+ * @param context a hx509 context.
+ * @param to the store to merge into.
+ * @param from the store to copy the object from.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from)
 {
@@ -343,6 +516,21 @@ hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from)
     return hx509_certs_iter(context, from, certs_merge_func, to);
 }
 
+/**
+ * Same a hx509_certs_merge() but use a lock and name to describe the
+ * from source.
+ *
+ * @param context a hx509 context.
+ * @param to the store to merge into.
+ * @param lock a lock that unlocks the certificates store, use NULL to
+ * select no password/certifictes/prompt lock (see @ref page_lock).
+ * @param name name of the source store
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_append(hx509_context context,
                   hx509_certs to,
@@ -360,6 +548,18 @@ hx509_certs_append(hx509_context context,
     return ret;
 }
 
+/**
+ * Get one random certificate from the certificate store.
+ *
+ * @param context a hx509 context.
+ * @param certs a certificate store to get the certificate from.
+ * @param c return certificate, should be freed with hx509_cert_free().
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_get_one_cert(hx509_context context, hx509_certs certs, hx509_cert *c)
 {
@@ -388,6 +588,21 @@ certs_info_stdio(void *ctx, const char *str)
     return 0;
 }
 
+/**
+ * Print some info about the certificate store.
+ *
+ * @param context a hx509 context.
+ * @param certs certificate store to print information about.
+ * @param func function that will get each line of the information, if
+ * NULL is used the data is printed on a FILE descriptor that should
+ * be passed in ctx, if ctx also is NULL, stdout is used.
+ * @param ctx parameter to func.
+ *
+ * @return Returns an hx509 error code.
+ *
+ * @ingroup hx509_keyset
+ */
+
 int
 hx509_certs_info(hx509_context context, 
                 hx509_certs certs,
index 269afd03b10a1e0c9f44b451eca987d704cd71de..87b97af401c5097c5188c6a6539ce0dcc0e1f08d 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_file.c 21314 2007-06-25 18:45:07Z lha $");
+RCSID("$Id: ks_file.c 22465 2008-01-16 14:25:24Z lha $");
 
 typedef enum { USE_PEM, USE_DER } outformat;
 
@@ -289,19 +289,25 @@ struct pem_formats {
 };
 
 
+struct pem_ctx {
+    int flags;
+    struct hx509_collector *c;
+};
+
 static int
 pem_func(hx509_context context, const char *type,
         const hx509_pem_header *header,
         const void *data, size_t len, void *ctx)
 {
-    struct hx509_collector *c = ctx;
-    int ret, j;
+    struct pem_ctx *pem_ctx = (struct pem_ctx*)ctx;
+    int ret = 0, j;
 
     for (j = 0; j < sizeof(formats)/sizeof(formats[0]); j++) {
        const char *q = formats[j].name;
        if (strcasecmp(type, q) == 0) {
-           ret = (*formats[j].func)(context, NULL, c,  header, data, len);
-           break;
+           ret = (*formats[j].func)(context, NULL, pem_ctx->c,  header, data, len);
+           if (ret == 0)
+               break;
        }
     }
     if (j == sizeof(formats)/sizeof(formats[0])) {
@@ -310,6 +316,8 @@ pem_func(hx509_context context, const char *type,
                               "Found no matching PEM format for %s", type);
        return ret;
     }
+    if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL))
+       return ret;
     return 0;
 }
 
@@ -324,9 +332,12 @@ file_init_common(hx509_context context,
 {
     char *p, *pnext;
     struct ks_file *f = NULL;
-    struct hx509_collector *c = NULL;
     hx509_private_key *keys = NULL;
     int ret;
+    struct pem_ctx pem_ctx;
+
+    pem_ctx.flags = flags;
+    pem_ctx.c = NULL;
 
     *data = NULL;
 
@@ -361,7 +372,7 @@ file_init_common(hx509_context context,
        return 0;
     }
 
-    ret = _hx509_collector_alloc(context, lock, &c);
+    ret = _hx509_collector_alloc(context, lock, &pem_ctx.c);
     if (ret)
        goto out;
 
@@ -381,7 +392,7 @@ file_init_common(hx509_context context,
            goto out;
        }
 
-       ret = hx509_pem_read(context, f, pem_func, c);
+       ret = hx509_pem_read(context, f, pem_func, &pem_ctx);
        fclose(f);                   
        if (ret != 0 && ret != HX509_PARSING_KEY_FAILED)
            goto out;
@@ -397,7 +408,7 @@ file_init_common(hx509_context context,
            }
 
            for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
-               ret = (*formats[i].func)(context, p, c, NULL, ptr, length);
+               ret = (*formats[i].func)(context, p, pem_ctx.c, NULL, ptr, length);
                if (ret == 0)
                    break;
            }
@@ -407,11 +418,11 @@ file_init_common(hx509_context context,
        }
     }
 
-    ret = _hx509_collector_collect_certs(context, c, &f->certs);
+    ret = _hx509_collector_collect_certs(context, pem_ctx.c, &f->certs);
     if (ret)
        goto out;
 
-    ret = _hx509_collector_collect_private_keys(context, c, &keys);
+    ret = _hx509_collector_collect_private_keys(context, pem_ctx.c, &keys);
     if (ret == 0) {
        int i;
 
@@ -428,8 +439,9 @@ out:
            free(f->fn);
        free(f);
     }
-    if (c)
-       _hx509_collector_free(c);
+    if (pem_ctx.c)
+       _hx509_collector_free(pem_ctx.c);
+
     return ret;
 }
 
index 33c4d6774b37ed3aaa5cc3eb0db62ef28c228380..f8181975d9d5ce43db5663339cb384c73c95798b 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_keychain.c 21097 2007-06-16 07:00:49Z lha $");
+RCSID("$Id: ks_keychain.c 22084 2007-11-16 20:12:30Z lha $");
 
 #ifdef HAVE_FRAMEWORK_SECURITY
 
 #include <Security/Security.h>
 
-/* Missing function decls */
+/* Missing function decls in pre Leopard */
+#ifdef NEED_SECKEYGETCSPHANDLE_PROTO
 OSStatus SecKeyGetCSPHandle(SecKeyRef, CSSM_CSP_HANDLE *);
 OSStatus SecKeyGetCredentials(SecKeyRef, CSSM_ACL_AUTHORIZATION_TAG,
                              int, const CSSM_ACCESS_CREDENTIALS **);
 #define kSecCredentialTypeDefault 0
+#endif
 
 
 static int
@@ -50,7 +52,7 @@ getAttribute(SecKeychainItemRef itemRef, SecItemAttr item,
             SecKeychainAttributeList **attrs)
 {           
     SecKeychainAttributeInfo attrInfo;
-    uint32 attrFormat = 0;
+    UInt32 attrFormat = 0;
     OSStatus ret;
 
     *attrs = NULL;
@@ -408,7 +410,7 @@ keychain_iter(hx509_context context,
 {
     SecKeychainAttributeList *attrs = NULL;
     SecKeychainAttributeInfo attrInfo;
-    uint32 attrFormat[1] = { 0 };
+    UInt32 attrFormat[1] = { 0 };
     SecKeychainItemRef itemRef;
     SecItemAttr item[1];
     struct iter *iter = cursor;
index e3066bbcfacd7420d0b18b1c27535d4dc08c1163..0d7c312c72413dfa2f462b699e0dc5bdba6145ec 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "hx_locl.h"
-RCSID("$Id: ks_p11.c 21387 2007-06-28 08:53:45Z lha $");
+RCSID("$Id: ks_p11.c 22071 2007-11-14 20:04:50Z lha $");
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -403,7 +403,7 @@ p11_get_session(hx509_context context,
      * prompter or known to work pin code.
      *
      * This code is very conversative and only uses the prompter in
-     * the hx509_lock, the reason is that its bad to try many
+     * the hx509_lock, the reason is that it's bad to try many
      * passwords on a pkcs11 token, it might lock up and have to be
      * unlocked by a administrator.
      *
index de326f2e2de65f2e12e723129d069c31ba44d0a0..e835aee35af036ea452934ddb7a92bde363afd36 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: lock.c 18452 2006-10-14 09:41:05Z lha $");
+RCSID("$Id: lock.c 22327 2007-12-15 04:49:37Z lha $");
+
+/**
+ * @page page_lock Locking and unlocking certificates and encrypted data.
+ *
+ * See the library functions here: @ref hx509_lock
+ */
 
 struct hx509_lock_data {
     struct _hx509_password password;
index 5198633b1e52b37b120e3c7330c61d007ebb9861..3f0806ddc01ecd553d6abad287b2ea90095861e9 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: name.c 20891 2007-06-04 22:51:41Z lha $");
+#include <wind.h>
+RCSID("$Id: name.c 22583 2008-02-11 20:46:21Z lha $");
 
-/* 
- * name parsing from rfc2253
- * fix so parsing rfc1779 works too 
- * rfc3280
+/**
+ * @page page_name PKIX/X.509 Names
+ *
+ * There are several names in PKIX/X.509, GeneralName and Name.
+ *
+ * A Name consists of an ordered list of Relative Distinguished Names
+ * (RDN). Each RDN consists of an unordered list of typed strings. The
+ * types are defined by OID and have long and short description. For
+ * example id-at-commonName (2.5.4.3) have the long name CommonName
+ * and short name CN. The string itself can be of serveral encoding,
+ * UTF8, UTF16, Teltex string, etc. The type limit what encoding
+ * should be used.
+ *
+ * GeneralName is a broader nametype that can contains al kind of
+ * stuff like Name, IP addresses, partial Name, etc.
+ *
+ * Name is mapped into a hx509_name object.
+ *
+ * Parse and string name into a hx509_name object with hx509_parse_name(),
+ * make it back into string representation with hx509_name_to_string().
+ *
+ * Name string are defined rfc2253, rfc1779 and X.501.
+ *
+ * See the library functions here: @ref hx509_name
  */
 
 static const struct {
     const char *n;
     const heim_oid *(*o)(void);
+    wind_profile_flags flags;
 } no[] = {
     { "C", oid_id_at_countryName },
     { "CN", oid_id_at_commonName },
@@ -153,6 +175,18 @@ stringtooid(const char *name, size_t len, heim_oid *oid)
     return ret;
 }
 
+/**
+ * Convert the hx509 name object into a printable string.
+ * The resulting string should be freed with free().
+ *
+ * @param name name to print
+ * @param str the string to return
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_to_string(const hx509_name name, char **str)
 {
@@ -247,82 +281,185 @@ _hx509_Name_to_string(const Name *n, char **str)
     return 0;
 }
 
-/*
- * XXX this function is broken, it needs to compare code points, not
- * bytes.
- */
+#define COPYCHARARRAY(_ds,_el,_l,_n)           \
+        (_l) = strlen(_ds->u._el);             \
+       (_n) = malloc((_l) * sizeof((_n)[0]));  \
+       if ((_n) == NULL)                       \
+           return ENOMEM;                      \
+       for (i = 0; i < (_l); i++)              \
+           (_n)[i] = _ds->u._el[i]
 
-int
-_hx509_name_ds_cmp(const DirectoryString *ds1, const DirectoryString *ds2)
+
+#define COPYVALARRAY(_ds,_el,_l,_n)            \
+        (_l) = _ds->u._el.length;              \
+       (_n) = malloc((_l) * sizeof((_n)[0]));  \
+       if ((_n) == NULL)                       \
+           return ENOMEM;                      \
+       for (i = 0; i < (_l); i++)              \
+           (_n)[i] = _ds->u._el.data[i]
+
+#define COPYVOIDARRAY(_ds,_el,_l,_n)           \
+        (_l) = _ds->u._el.length;              \
+       (_n) = malloc((_l) * sizeof((_n)[0]));  \
+       if ((_n) == NULL)                       \
+           return ENOMEM;                      \
+       for (i = 0; i < (_l); i++)              \
+           (_n)[i] = ((unsigned char *)_ds->u._el.data)[i]
+
+
+
+static int
+dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen)
 {
-    int c;
+    wind_profile_flags flags = 0;
+    size_t i, len;
+    int ret;
+    uint32_t *name;
 
-    c = ds1->element - ds2->element;
-    if (c)
-       return c;
+    *rname = NULL;
+    *rlen = 0;
 
-    switch(ds1->element) {
+    switch(ds->element) {
     case choice_DirectoryString_ia5String:
-       c = strcmp(ds1->u.ia5String, ds2->u.ia5String);
-       break;
-    case choice_DirectoryString_teletexString:
-       c = der_heim_octet_string_cmp(&ds1->u.teletexString,
-                                 &ds2->u.teletexString);
+       COPYCHARARRAY(ds, ia5String, len, name);
        break;
     case choice_DirectoryString_printableString:
-       c = strcasecmp(ds1->u.printableString, ds2->u.printableString);
+       flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;
+       COPYCHARARRAY(ds, printableString, len, name);
        break;
-    case choice_DirectoryString_utf8String:
-       c = strcmp(ds1->u.utf8String, ds2->u.utf8String);
+    case choice_DirectoryString_teletexString:
+       COPYVOIDARRAY(ds, teletexString, len, name);
+       break;
+    case choice_DirectoryString_bmpString:
+       COPYVALARRAY(ds, bmpString, len, name);
        break;
     case choice_DirectoryString_universalString:
-       c = der_heim_universal_string_cmp(&ds1->u.universalString,
-                                         &ds2->u.universalString);
+       COPYVALARRAY(ds, universalString, len, name);
        break;
-    case choice_DirectoryString_bmpString:
-       c = der_heim_bmp_string_cmp(&ds1->u.bmpString,
-                                   &ds2->u.bmpString);
+    case choice_DirectoryString_utf8String:
+       ret = wind_utf8ucs4_length(ds->u.utf8String, &len);
+       if (ret)
+           return ret;
+       name = malloc(len * sizeof(name[0]));
+       if (name == NULL)
+           return ENOMEM;
+       ret = wind_utf8ucs4(ds->u.utf8String, name, &len);
+       if (ret)
+           return ret;
        break;
     default:
-       c = 1;
-       break;
+       _hx509_abort("unknown directory type: %d", ds->element);
+    }
+
+    *rlen = len;
+    /* try a couple of times to get the length right, XXX gross */
+    for (i = 0; i < 4; i++) {
+       *rlen = *rlen * 2;
+       *rname = malloc(*rlen * sizeof((*rname)[0]));
+
+       ret = wind_stringprep(name, len, *rname, rlen,
+                             WIND_PROFILE_LDAP|flags);
+       if (ret == WIND_ERR_OVERRUN) {
+           free(*rname);
+           *rname = NULL;
+           continue;
+       } else
+           break;
+    }
+    free(name);
+    if (ret) {
+       if (*rname)
+           free(*rname);
+       *rname = NULL;
+       *rlen = 0;
+       return ret;
+    }
+
+    return 0;
+}
+
+int
+_hx509_name_ds_cmp(const DirectoryString *ds1,
+                  const DirectoryString *ds2,
+                  int *diff)
+{
+    uint32_t *ds1lp, *ds2lp;
+    size_t ds1len, ds2len;
+    int ret;
+
+    ret = dsstringprep(ds1, &ds1lp, &ds1len);
+    if (ret)
+       return ret;
+    ret = dsstringprep(ds2, &ds2lp, &ds2len);
+    if (ret) {
+       free(ds1lp);
+       return ret;
     }
-    return c;
+
+    if (ds1len != ds2len)
+       *diff = ds1len - ds2len;
+    else
+       *diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));
+
+    free(ds1lp);
+    free(ds2lp);
+
+    return 0;
 }
 
 int
-_hx509_name_cmp(const Name *n1, const Name *n2)
+_hx509_name_cmp(const Name *n1, const Name *n2, int *c)
 {
-    int i, j, c;
+    int ret, i, j;
 
-    c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
-    if (c)
-       return c;
+    *c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
+    if (*c)
+       return 0;
 
     for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
-       c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
-       if (c)
-           return c;
+       *c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
+       if (*c)
+           return 0;
 
        for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
-           c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
-                                &n1->u.rdnSequence.val[i].val[j].type);
-           if (c)
-               return c;
+           *c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
+                                 &n1->u.rdnSequence.val[i].val[j].type);
+           if (*c)
+               return 0;
                             
-           c = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
-                                  &n2->u.rdnSequence.val[i].val[j].value);
-           if (c)
-               return c;
+           ret = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
+                                    &n2->u.rdnSequence.val[i].val[j].value,
+                                    c);
+           if (ret)
+               return ret;
+           if (*c)
+               return 0;
        }
     }
+    *c = 0;
     return 0;
 }
 
+/**
+ * Compare to hx509 name object, useful for sorting.
+ *
+ * @param n1 a hx509 name object.
+ * @param n2 a hx509 name object.
+ *
+ * @return 0 the objects are the same, returns > 0 is n2 is "larger"
+ * then n2, < 0 if n1 is "smaller" then n2.
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_cmp(hx509_name n1, hx509_name n2)
 {
-    return _hx509_name_cmp(&n1->der_name, &n2->der_name);
+    int ret, diff;
+    ret = _hx509_name_cmp(&n1->der_name, &n2->der_name, &diff);
+    if (ret)
+       return ret;
+    return diff;
 }
 
 
@@ -341,19 +478,6 @@ _hx509_name_from_Name(const Name *n, hx509_name *name)
     return ret;
 }
 
-static int
-hx509_der_parse_name(const void *data, size_t length, hx509_name *name)
-{
-    int ret;
-    Name n;
-
-    *name = NULL;
-    ret = decode_Name(data, length, &n, NULL);
-    if (ret)
-       return ret;
-    return _hx509_name_from_Name(&n, name);
-}
-
 int
 _hx509_name_modify(hx509_context context,
                   Name *name, 
@@ -400,6 +524,18 @@ _hx509_name_modify(hx509_context context,
     return 0;
 }
 
+/**
+ * Parse a string into a hx509 name object.
+ *
+ * @param context A hx509 context.
+ * @param str a string to parse.
+ * @param name the resulting object, NULL in case of error.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_parse_name(hx509_context context, const char *str, hx509_name *name)
 {
@@ -492,6 +628,18 @@ out:
     return HX509_NAME_MALFORMED;
 }
 
+/**
+ * Copy a hx509 name object.
+ *
+ * @param context A hx509 cotext.
+ * @param from the name to copy from
+ * @param to the name to copy to
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_copy(hx509_context context, const hx509_name from, hx509_name *to)
 {
@@ -509,6 +657,17 @@ hx509_name_copy(hx509_context context, const hx509_name from, hx509_name *to)
     return 0;
 }
 
+/**
+ * Convert a hx509_name into a Name.
+ *
+ * @param from the name to copy from
+ * @param to the name to copy to
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_to_Name(const hx509_name from, Name *to)
 {
@@ -521,6 +680,19 @@ hx509_name_normalize(hx509_context context, hx509_name name)
     return 0;
 }
 
+/**
+ * Expands variables in the name using env. Variables are on the form
+ * ${name}. Useful when dealing with certificate templates.
+ *
+ * @param context A hx509 cotext.
+ * @param name the name to expand.
+ * @param env environment variable to expand.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_expand(hx509_context context,
                  hx509_name name,
@@ -539,6 +711,7 @@ hx509_name_expand(hx509_context context,
 
     for (i = 0 ; i < n->u.rdnSequence.len; i++) {
        for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
+           /** Only UTF8String rdnSequence names are allowed */
            /*
              THIS SHOULD REALLY BE:
              COMP = n->u.rdnSequence.val[i].val[j];
@@ -615,6 +788,13 @@ hx509_name_expand(hx509_context context,
     return 0;
 }
 
+/**
+ * Free a hx509 name object, upond return *name will be NULL.
+ *
+ * @param name a hx509 name object to be freed.
+ *
+ * @ingroup hx509_name
+ */
 
 void
 hx509_name_free(hx509_name *name)
@@ -625,37 +805,61 @@ hx509_name_free(hx509_name *name)
     *name = NULL;
 }
 
+/**
+ * Convert a DER encoded name info a string.
+ *
+ * @param data data to a DER/BER encoded name
+ * @param length length of data
+ * @param str the resulting string, is NULL on failure.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_unparse_der_name(const void *data, size_t length, char **str)
 {
-    hx509_name name;
+    Name name;
     int ret;
 
-    ret = hx509_der_parse_name(data, length, &name);
+    *str = NULL;
+
+    ret = decode_Name(data, length, &name, NULL);
     if (ret)
        return ret;
-    
-    ret = hx509_name_to_string(name, str);
-    hx509_name_free(&name);
+    ret = _hx509_Name_to_string(&name, str);
+    free_Name(&name);
     return ret;
 }
 
+/**
+ * Convert a hx509_name object to DER encoded name.
+ *
+ * @param name name to concert
+ * @param os data to a DER encoded name, free the resulting octet
+ * string with hx509_xfree(os->data).
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
-hx509_name_to_der_name(const hx509_name name, void **data, size_t *length)
+hx509_name_binary(const hx509_name name, heim_octet_string *os)
 {
     size_t size;
     int ret;
 
-    ASN1_MALLOC_ENCODE(Name, *data, *length, &name->der_name, &size, ret);
+    ASN1_MALLOC_ENCODE(Name, os->data, os->length, &name->der_name, &size, ret);
     if (ret)
        return ret;
-    if (*length != size)
+    if (os->length != size)
        _hx509_abort("internal ASN.1 encoder error");
 
     return 0;
 }
 
-
 int
 _hx509_unparse_Name(const Name *aname, char **str)
 {
@@ -671,12 +875,33 @@ _hx509_unparse_Name(const Name *aname, char **str)
     return ret;
 }
 
+/**
+ * Unparse the hx509 name in name into a string.
+ *
+ * @param name the name to check if its empty/null.
+ *
+ * @return non zero if the name is empty/null.
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_name_is_null_p(const hx509_name name)
 {
     return name->der_name.u.rdnSequence.len == 0;
 }
 
+/**
+ * Unparse the hx509 name in name into a string.
+ *
+ * @param name the name to print
+ * @param str an allocated string returns the name in string form
+ *
+ * @return An hx509 error code, see krb5_get_error_string().
+ *
+ * @ingroup hx509_name
+ */
+
 int
 hx509_general_name_unparse(GeneralName *name, char **str)
 {
index e90f8f34b06786485fdcea70b7839e2f5ad640de..eb0ecd2bdefb53f3c95c212673bc50f500cd6b05 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: peer.c 21481 2007-07-10 16:33:23Z lha $");
+RCSID("$Id: peer.c 22345 2007-12-26 19:03:51Z lha $");
+
+/**
+ * @page page_peer Hx509 crypto selecting functions
+ *
+ * Peer info structures are used togeter with hx509_crypto_select() to
+ * select the best avaible crypto algorithm to use.
+ *
+ * See the library functions here: @ref hx509_peer
+ */
+
+/**
+ * Allocate a new peer info structure an init it to default values.
+ *
+ * @param context A hx509 context.
+ * @param peer return an allocated peer, free with hx509_peer_info_free().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
 
 int
 hx509_peer_info_alloc(hx509_context context, hx509_peer_info *peer)
@@ -59,6 +79,14 @@ free_cms_alg(hx509_peer_info peer)
     }
 }
 
+/**
+ * Free a peer info structure.
+ *
+ * @param peer peer info to be freed.
+ *
+ * @ingroup hx509_peer
+ */
+
 void
 hx509_peer_info_free(hx509_peer_info peer)
 {
@@ -71,6 +99,17 @@ hx509_peer_info_free(hx509_peer_info peer)
     free(peer);
 }
 
+/**
+ * Set the certificate that remote peer is using.
+ *
+ * @param peer peer info to update
+ * @param cert cerificate of the remote peer.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
+
 int
 hx509_peer_info_set_cert(hx509_peer_info peer,
                         hx509_cert cert)
@@ -81,6 +120,19 @@ hx509_peer_info_set_cert(hx509_peer_info peer,
     return 0;
 }
 
+/**
+ * Set the algorithms that the peer supports.
+ *
+ * @param context A hx509 context.
+ * @param peer the peer to set the new algorithms for
+ * @param val array of supported AlgorithmsIdentiers
+ * @param len length of array val.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_peer
+ */
+
 int
 hx509_peer_info_set_cms_algs(hx509_context context,
                             hx509_peer_info peer,
index e6f71ea2cebc927cc993f868850dd4d3a8bb5ff4..c1594ff04764be937f3f99d695262443534dd1c7 100644 (file)
  */
 
 #include "hx_locl.h"
-RCSID("$Id: print.c 21381 2007-06-28 08:29:22Z lha $");
+RCSID("$Id: print.c 22538 2008-01-27 13:05:47Z lha $");
 
+/**
+ * @page page_print Hx509 printing functions
+ *
+ * See the library functions here: @ref hx509_print
+ */
 
 struct hx509_validate_ctx_data {
     int flags;
@@ -75,15 +80,31 @@ Time2string(const Time *T, char **str)
     return 0;
 }
 
+/**
+ * Helper function to print on stdout for:
+ * - hx509_oid_print(),
+ * - hx509_bitstring_print(),
+ * - hx509_validate_ctx_set_print().
+ *
+ * @param ctx the context to the print function. If the ctx is NULL,
+ * stdout is used.
+ * @param fmt the printing format.
+ * @param va the argumet list.
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_print_stdout(void *ctx, const char *fmt, va_list va)
 {
     FILE *f = ctx;
+    if (f == NULL)
+       f = stdout;
     vfprintf(f, fmt, va);
 }
 
-void
-hx509_print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
+static void
+print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
 {
     va_list va;
     va_start(va, fmt);
@@ -91,36 +112,82 @@ hx509_print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
     va_end(va);
 }
 
+/**
+ * Print a oid to a string.
+ * 
+ * @param oid oid to print
+ * @param str allocated string, free with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 int
 hx509_oid_sprint(const heim_oid *oid, char **str)
 {
     return der_print_heim_oid(oid, '.', str);
 }
 
+/**
+ * Print a oid using a hx509_vprint_func function. To print to stdout
+ * use hx509_print_stdout().
+ * 
+ * @param oid oid to print
+ * @param func hx509_vprint_func to print with.
+ * @param ctx context variable to hx509_vprint_func function.
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_oid_print(const heim_oid *oid, hx509_vprint_func func, void *ctx)
 {
     char *str;
     hx509_oid_sprint(oid, &str);
-    hx509_print_func(func, ctx, "%s", str);
+    print_func(func, ctx, "%s", str);
     free(str);
 }
 
+/**
+ * Print a bitstring using a hx509_vprint_func function. To print to
+ * stdout use hx509_print_stdout().
+ * 
+ * @param b bit string to print.
+ * @param func hx509_vprint_func to print with.
+ * @param ctx context variable to hx509_vprint_func function.
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_bitstring_print(const heim_bit_string *b,
                      hx509_vprint_func func, void *ctx)
 {
     int i;
-    hx509_print_func(func, ctx, "\tlength: %d\n\t", b->length);
+    print_func(func, ctx, "\tlength: %d\n\t", b->length);
     for (i = 0; i < (b->length + 7) / 8; i++)
-       hx509_print_func(func, ctx, "%02x%s%s",
-                        ((unsigned char *)b->data)[i], 
-                        i < (b->length - 7) / 8
-                        && (i == 0 || (i % 16) != 15) ? ":" : "",
-                        i != 0 && (i % 16) == 15 ?
-                        (i <= ((b->length + 7) / 8 - 2) ? "\n\t" : "\n"):"");
+       print_func(func, ctx, "%02x%s%s",
+                  ((unsigned char *)b->data)[i], 
+                  i < (b->length - 7) / 8
+                  && (i == 0 || (i % 16) != 15) ? ":" : "",
+                  i != 0 && (i % 16) == 15 ?
+                  (i <= ((b->length + 7) / 8 - 2) ? "\n\t" : "\n"):"");
 }
 
+/**
+ * Print certificate usage for a certificate to a string.
+ * 
+ * @param context A hx509 context.
+ * @param c a certificate print the keyusage for.
+ * @param s the return string with the keysage printed in to, free
+ * with hx509_xfree().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 int
 hx509_cert_keyusage_print(hx509_context context, hx509_cert c, char **s)
 {
@@ -268,9 +335,6 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
     status->haveAKI = 1;
     check_Null(ctx, status, cf, e);
 
-    status->haveSKI = 1;
-    check_Null(ctx, status, cf, e);
-
     ret = decode_AuthorityKeyIdentifier(e->extnValue.data, 
                                        e->extnValue.length,
                                        &ai, &size);
@@ -298,6 +362,56 @@ check_authorityKeyIdentifier(hx509_validate_ctx ctx,
     return 0;
 }
 
+static int
+check_extKeyUsage(hx509_validate_ctx ctx, 
+                 struct cert_status *status,
+                 enum critical_flag cf,
+                 const Extension *e)
+{
+    ExtKeyUsage eku;
+    size_t size, i;
+    int ret;
+
+    check_Null(ctx, status, cf, e);
+
+    ret = decode_ExtKeyUsage(e->extnValue.data, 
+                            e->extnValue.length,
+                            &eku, &size);
+    if (ret) {
+       validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+                      "Decoding ExtKeyUsage failed: %d", ret);
+       return 1;
+    }
+    if (size != e->extnValue.length) {
+       validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+                      "Padding data in EKU");
+       free_ExtKeyUsage(&eku);
+       return 1;
+    }
+    if (eku.len == 0) {
+       validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+                      "ExtKeyUsage length is 0");
+       return 1;
+    }
+
+    for (i = 0; i < eku.len; i++) {
+       char *str;
+       ret = der_print_heim_oid (&eku.val[i], '.', &str);
+       if (ret) {
+           validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
+                          "\tEKU: failed to print oid %d", i);
+           free_ExtKeyUsage(&eku);
+           return 1;
+       }
+       validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
+                      "\teku-%d: %s\n", i, str);;
+       free(str);
+    }
+
+    free_ExtKeyUsage(&eku);
+
+    return 0;
+}
 
 static int
 check_pkinit_san(hx509_validate_ctx ctx, heim_any *a)
@@ -664,7 +778,7 @@ struct {
     { ext(policyMappings, Null), M_N_C },
     { ext(authorityKeyIdentifier, authorityKeyIdentifier), M_N_C },
     { ext(policyConstraints, Null), D_C },
-    { ext(extKeyUsage, Null), D_C },
+    { ext(extKeyUsage, extKeyUsage), D_C },
     { ext(freshestCRL, Null), M_N_C },
     { ext(inhibitAnyPolicy, Null), M_C },
 #undef ext
@@ -679,6 +793,18 @@ struct {
     { NULL }
 };
 
+/**
+ * Allocate a hx509 validation/printing context.
+ * 
+ * @param context A hx509 context.
+ * @param ctx a new allocated hx509 validation context, free with
+ * hx509_validate_ctx_free().
+
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 int
 hx509_validate_ctx_init(hx509_context context, hx509_validate_ctx *ctx)
 {
@@ -689,6 +815,18 @@ hx509_validate_ctx_init(hx509_context context, hx509_validate_ctx *ctx)
     return 0;
 }
 
+/**
+ * Set the printing functions for the validation context.
+ * 
+ * @param ctx a hx509 valication context.
+ * @param func the printing function to usea.
+ * @param c the context variable to the printing function.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_validate_ctx_set_print(hx509_validate_ctx ctx, 
                             hx509_vprint_func func,
@@ -698,18 +836,50 @@ hx509_validate_ctx_set_print(hx509_validate_ctx ctx,
     ctx->ctx = c;
 }
 
+/**
+ * Add flags to control the behaivor of the hx509_validate_cert()
+ * function.
+ * 
+ * @param ctx A hx509 validation context.
+ * @param flags flags to add to the validation context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_validate_ctx_add_flags(hx509_validate_ctx ctx, int flags)
 {
     ctx->flags |= flags;
 }
 
+/**
+ * Free an hx509 validate context.
+ * 
+ * @param ctx the hx509 validate context to free.
+ *
+ * @ingroup hx509_print
+ */
+
 void
 hx509_validate_ctx_free(hx509_validate_ctx ctx)
 {
     free(ctx);
 }
 
+/**
+ * Validate/Print the status of the certificate.
+ * 
+ * @param context A hx509 context.
+ * @param ctx A hx509 validation context.
+ * @param cert the cerificate to validate/print.
+
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_print
+ */
+
 int
 hx509_validate_cert(hx509_context context,
                    hx509_validate_ctx ctx,
index ddcb17ee38d82ae3faf1fb460556cd0ca8128881..2010f945f0eff6366493c1473cd7f1ea12258230 100644 (file)
  * SUCH DAMAGE. 
  */
 
+/**
+ * @page page_revoke Revocation methods
+ *
+ * There are two revocation method for PKIX/X.509: CRL and OCSP.
+ * Revocation is needed if the private key is lost and
+ * stolen. Depending on how picky you are, you might want to make
+ * revocation for destroyed private keys too (smartcard broken), but
+ * that should not be a problem.
+ *
+ * CRL is a list of certifiates that have expired.
+ *
+ * OCSP is an online checking method where the requestor sends a list
+ * of certificates to the OCSP server to return a signed reply if they
+ * are valid or not. Some services sends a OCSP reply as part of the
+ * hand-shake to make the revoktion decision simpler/faster for the
+ * client.
+ */
+
 #include "hx_locl.h"
-RCSID("$Id: revoke.c 21153 2007-06-18 21:55:46Z lha $");
+RCSID("$Id: revoke.c 22583 2008-02-11 20:46:21Z lha $");
 
 struct revoke_crl {
     char *path;
     time_t last_modfied;
     CRLCertificateList crl;
     int verified;
+    int failed_verify;
 };
 
 struct revoke_ocsp {
@@ -51,6 +70,7 @@ struct revoke_ocsp {
 
 
 struct hx509_revoke_ctx_data {
+    unsigned ref;
     struct {
        struct revoke_crl *val;
        size_t len;
@@ -61,6 +81,17 @@ struct hx509_revoke_ctx_data {
     } ocsps;
 };
 
+/**
+ * Allocate a revokation context. Free with hx509_revoke_free().
+ *
+ * @param context A hx509 context.
+ * @param ctx returns a newly allocated revokation context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
 int
 hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
 {
@@ -68,6 +99,7 @@ hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
     if (*ctx == NULL)
        return ENOMEM;
 
+    (*ctx)->ref = 1;
     (*ctx)->crls.len = 0;
     (*ctx)->crls.val = NULL;
     (*ctx)->ocsps.len = 0;
@@ -76,6 +108,19 @@ hx509_revoke_init(hx509_context context, hx509_revoke_ctx *ctx)
     return 0;
 }
 
+hx509_revoke_ctx
+_hx509_revoke_ref(hx509_revoke_ctx ctx)
+{
+    if (ctx == NULL)
+       return NULL;
+    if (ctx->ref <= 0)
+       _hx509_abort("revoke ctx refcount <= 0");
+    ctx->ref++;
+    if (ctx->ref == 0)
+       _hx509_abort("revoke ctx refcount == 0");
+    return ctx;
+}
+
 static void
 free_ocsp(struct revoke_ocsp *ocsp)
 {
@@ -85,6 +130,14 @@ free_ocsp(struct revoke_ocsp *ocsp)
     hx509_cert_free(ocsp->signer);
 }
 
+/**
+ * Free a hx509 revokation context.
+ *
+ * @param ctx context to be freed
+ *
+ * @ingroup hx509_revoke
+ */
+
 void
 hx509_revoke_free(hx509_revoke_ctx *ctx)
 {
@@ -93,6 +146,11 @@ hx509_revoke_free(hx509_revoke_ctx *ctx)
     if (ctx == NULL || *ctx == NULL)
        return;
 
+    if ((*ctx)->ref <= 0)
+       _hx509_abort("revoke ctx refcount <= 0 on free");
+    if (--(*ctx)->ref > 0)
+       return;
+
     for (i = 0; i < (*ctx)->crls.len; i++) {
        free((*ctx)->crls.val[i].path);
        free_CRLCertificateList(&(*ctx)->crls.val[i].crl);
@@ -150,7 +208,7 @@ verify_ocsp(hx509_context context,
 
     /*
      * If signer certificate isn't the CA certificate, lets check the
-     * its the CA that signed the signer certificate and the OCSP EKU
+     * it is the CA that signed the signer certificate and the OCSP EKU
      * is set.
      */
     if (hx509_cert_cmp(signer, parent) != 0) {
@@ -324,6 +382,18 @@ load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
     return 0;
 }
 
+/**
+ * Add a OCSP file to the revokation context.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param path path to file that is going to be added to the context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
 int
 hx509_revoke_add_ocsp(hx509_context context,
                      hx509_revoke_ctx ctx,
@@ -380,6 +450,7 @@ hx509_revoke_add_ocsp(hx509_context context,
 
 static int
 verify_crl(hx509_context context,
+          hx509_revoke_ctx ctx,
           CRLCertificateList *crl,
           time_t time_now,
           hx509_certs certs,
@@ -391,52 +462,44 @@ verify_crl(hx509_context context,
     int ret;
        
     t = _hx509_Time2time_t(&crl->tbsCertList.thisUpdate);
-    if (t > time_now)
+    if (t > time_now) {
+       hx509_set_error_string(context, 0, HX509_CRL_USED_BEFORE_TIME,
+                              "CRL used before time");
        return HX509_CRL_USED_BEFORE_TIME;
+    }
 
-    if (crl->tbsCertList.nextUpdate == NULL)
+    if (crl->tbsCertList.nextUpdate == NULL) {
+       hx509_set_error_string(context, 0, HX509_CRL_INVALID_FORMAT,
+                              "CRL missing nextUpdate");
        return HX509_CRL_INVALID_FORMAT;
+    }
 
     t = _hx509_Time2time_t(crl->tbsCertList.nextUpdate);
-    if (t < time_now)
+    if (t < time_now) {
+       hx509_set_error_string(context, 0, HX509_CRL_USED_AFTER_TIME,
+                              "CRL used after time");
        return HX509_CRL_USED_AFTER_TIME;
+    }
 
     _hx509_query_clear(&q);
        
-    q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
-    q.subject_name = &crl->tbsCertList.issuer;
+    /*
+     * If it's the signer have CRLSIGN bit set, use that as the signer
+     * cert for the certificate, otherwise, search for a certificate.
+     */
+    if (_hx509_check_key_usage(context, parent, 1 << 6, FALSE) == 0) {
+       signer = hx509_cert_ref(parent);
+    } else {
+       q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
+       q.match |= HX509_QUERY_KU_CRLSIGN;
+       q.subject_name = &crl->tbsCertList.issuer;
        
-    ret = hx509_certs_find(context, certs, &q, &signer);
-    if (ret)
-       return ret;
-
-    /* verify is parent or CRLsigner */
-    if (hx509_cert_cmp(signer, parent) != 0) {
-       Certificate *p = _hx509_get_cert(parent);
-       Certificate *s = _hx509_get_cert(signer);
-
-       ret = _hx509_cert_is_parent_cmp(s, p, 0);
-       if (ret != 0) {
-           ret = HX509_PARENT_NOT_CA;
-           hx509_set_error_string(context, 0, ret, "Revoke CRL signer is "
-                                  "doesn't have CA as signer certificate");
-           goto out;
-       }
-
-       ret = _hx509_verify_signature_bitstring(context,
-                                               p,
-                                               &s->signatureAlgorithm,
-                                               &s->tbsCertificate._save,
-                                               &s->signatureValue);
+       ret = hx509_certs_find(context, certs, &q, &signer);
        if (ret) {
            hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
-                                  "CRL signer signature invalid");
-           goto out;
+                                  "Failed to find certificate for CRL");
+           return ret;
        }
-
-       ret = _hx509_check_key_usage(context, signer, 1 << 6, TRUE); /* crl */
-       if (ret != 0)
-           goto out;
     }
 
     ret = _hx509_verify_signature_bitstring(context,
@@ -450,6 +513,44 @@ verify_crl(hx509_context context,
        goto out;
     }
 
+    /* 
+     * If signer is not CA cert, need to check revoke status of this
+     * CRL signing cert too, this include all parent CRL signer cert
+     * up to the root *sigh*, assume root at least hve CERTSIGN flag
+     * set.
+     */
+    while (_hx509_check_key_usage(context, signer, 1 << 5, TRUE)) {
+       hx509_cert crl_parent;
+
+       _hx509_query_clear(&q);
+       
+       q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
+       q.match |= HX509_QUERY_KU_CRLSIGN;
+       q.subject_name = &_hx509_get_cert(signer)->tbsCertificate.issuer;
+       
+       ret = hx509_certs_find(context, certs, &q, &crl_parent);
+       if (ret) {
+           hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
+                                  "Failed to find parent of CRL signer");
+           goto out;
+       }
+
+       ret = hx509_revoke_verify(context,
+                                 ctx, 
+                                 certs,
+                                 time_now,
+                                 signer,
+                                 crl_parent);
+       hx509_cert_free(signer);
+       signer = crl_parent;
+       if (ret) {
+           hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
+                                  "Failed to verify revoke "
+                                  "status of CRL signer");
+           goto out;
+       }
+    }
+
 out:
     hx509_cert_free(signer);
 
@@ -485,6 +586,18 @@ load_crl(const char *path, time_t *t, CRLCertificateList *crl)
     return 0;
 }
 
+/**
+ * Add a CRL file to the revokation context.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param path path to file that is going to be added to the context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
 int
 hx509_revoke_add_crl(hx509_context context,
                     hx509_revoke_ctx ctx,
@@ -537,6 +650,23 @@ hx509_revoke_add_crl(hx509_context context,
     return ret;
 }
 
+/**
+ * Check that a certificate is not expired according to a revokation
+ * context. Also need the parent certificte to the check OCSP
+ * parent identifier.
+ *
+ * @param context hx509 context
+ * @param ctx hx509 revokation context
+ * @param certs
+ * @param now
+ * @param cert
+ * @param parent_cert
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
 
 int
 hx509_revoke_verify(hx509_context context,
@@ -551,6 +681,8 @@ hx509_revoke_verify(hx509_context context,
     unsigned long i, j, k;
     int ret;
 
+    hx509_clear_error_string(context);
+
     for (i = 0; i < ctx->ocsps.len; i++) {
        struct revoke_ocsp *ocsp = &ctx->ocsps.val[i];
        struct stat sb;
@@ -604,6 +736,10 @@ hx509_revoke_verify(hx509_context context,
            case choice_OCSPCertStatus_good:
                break;
            case choice_OCSPCertStatus_revoked:
+               hx509_set_error_string(context, 0, 
+                                      HX509_CERT_REVOKED,
+                                      "Certificate revoked by issuer in OCSP");
+               return HX509_CERT_REVOKED;
            case choice_OCSPCertStatus_unknown:
                continue;
            }
@@ -613,7 +749,7 @@ hx509_revoke_verify(hx509_context context,
                now + context->ocsp_time_diff)
                continue;
 
-           /* don't allow the next updte to be in the past */
+           /* don't allow the next update to be in the past */
            if (ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate) {
                if (*ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate < now)
                    continue;
@@ -627,11 +763,12 @@ hx509_revoke_verify(hx509_context context,
     for (i = 0; i < ctx->crls.len; i++) {
        struct revoke_crl *crl = &ctx->crls.val[i];
        struct stat sb;
+       int diff;
 
        /* check if cert.issuer == crls.val[i].crl.issuer */
        ret = _hx509_name_cmp(&c->tbsCertificate.issuer, 
-                             &crl->crl.tbsCertList.issuer);
-       if (ret)
+                             &crl->crl.tbsCertList.issuer, &diff);
+       if (ret || diff)
            continue;
 
        ret = stat(crl->path, &sb);
@@ -643,21 +780,32 @@ hx509_revoke_verify(hx509_context context,
                free_CRLCertificateList(&crl->crl);
                crl->crl = cl;
                crl->verified = 0;
+               crl->failed_verify = 0;
            }
        }
+       if (crl->failed_verify)
+           continue;
 
        /* verify signature in crl if not already done */
        if (crl->verified == 0) {
-           ret = verify_crl(context, &crl->crl, now, certs, parent_cert);
-           if (ret)
-               return ret;
+           ret = verify_crl(context, ctx, &crl->crl, now, certs, parent_cert);
+           if (ret) {
+               crl->failed_verify = 1;
+               continue;
+           }
            crl->verified = 1;
        }
-       
-       if (crl->crl.tbsCertList.crlExtensions)
-           for (j = 0; j < crl->crl.tbsCertList.crlExtensions->len; j++)
-               if (crl->crl.tbsCertList.crlExtensions->val[j].critical)
+
+       if (crl->crl.tbsCertList.crlExtensions) {
+           for (j = 0; j < crl->crl.tbsCertList.crlExtensions->len; j++) {
+               if (crl->crl.tbsCertList.crlExtensions->val[j].critical) {
+                   hx509_set_error_string(context, 0, 
+                                          HX509_CRL_UNKNOWN_EXTENSION,
+                                          "Unknown CRL extension");
                    return HX509_CRL_UNKNOWN_EXTENSION;
+               }
+           }
+       }
 
        if (crl->crl.tbsCertList.revokedCertificates == NULL)
            return 0;
@@ -667,7 +815,7 @@ hx509_revoke_verify(hx509_context context,
            time_t t;
 
            ret = der_heim_integer_cmp(&crl->crl.tbsCertList.revokedCertificates->val[j].userCertificate,
-                                  &c->tbsCertificate.serialNumber);
+                                      &c->tbsCertificate.serialNumber);
            if (ret != 0)
                continue;
 
@@ -680,7 +828,10 @@ hx509_revoke_verify(hx509_context context,
                    if (crl->crl.tbsCertList.revokedCertificates->val[j].crlEntryExtensions->val[k].critical)
                        return HX509_CRL_UNKNOWN_EXTENSION;
            
-           return HX509_CRL_CERT_REVOKED;
+           hx509_set_error_string(context, 0, 
+                                  HX509_CERT_REVOKED,
+                                  "Certificate revoked by issuer in CRL");
+           return HX509_CERT_REVOKED;
        }
 
        return 0;
@@ -689,6 +840,10 @@ hx509_revoke_verify(hx509_context context,
 
     if (context->flags & HX509_CTX_VERIFY_MISSING_OK)
        return 0;
+    hx509_set_error_string(context, HX509_ERROR_APPEND, 
+                          HX509_REVOKE_STATUS_MISSING,
+                          "No revoke status found for "
+                          "certificates");
     return HX509_REVOKE_STATUS_MISSING;
 }
 
@@ -785,6 +940,22 @@ out:
     return ret;
 }
 
+/**
+ * Create an OCSP request for a set of certificates.
+ *
+ * @param context a hx509 context
+ * @param reqcerts list of certificates to request ocsp data for
+ * @param pool certificate pool to use when signing
+ * @param signer certificate to use to sign the request
+ * @param digest the signing algorithm in the request, if NULL use the
+ * default signature algorithm,
+ * @param request the encoded request, free with free_heim_octet_string().
+ * @param nonce nonce in the request, free with free_heim_octet_string().
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
 
 int
 hx509_ocsp_request(hx509_context context,
@@ -813,41 +984,49 @@ hx509_ocsp_request(hx509_context context,
 
     ret = hx509_certs_iter(context, reqcerts, add_to_req, &ctx);
     hx509_cert_free(ctx.parent);
-    if (ret) {
-       free_OCSPRequest(&req);
-       return ret;
-    }
+    if (ret)
+       goto out;
     
     if (nonce) {
-
        req.tbsRequest.requestExtensions = 
            calloc(1, sizeof(*req.tbsRequest.requestExtensions));
        if (req.tbsRequest.requestExtensions == NULL) {
-           free_OCSPRequest(&req);
-           return ENOMEM;
+           ret = ENOMEM;
+           goto out;
        }
 
        es = req.tbsRequest.requestExtensions;
        
-       es->len = 1;
        es->val = calloc(es->len, sizeof(es->val[0]));
+       if (es->val == NULL) {
+           ret = ENOMEM;
+           goto out;
+       }
+       es->len = 1;
        
        ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);
-       if (ret)
-           abort();
-       
+       if (ret) {
+           free_OCSPRequest(&req);
+           return ret;
+       }
+
        es->val[0].extnValue.data = malloc(10);
        if (es->val[0].extnValue.data == NULL) {
-           free_OCSPRequest(&req);
-           return ENOMEM;
+           ret = ENOMEM;
+           goto out;
        }
        es->val[0].extnValue.length = 10;
        
        ret = RAND_bytes(es->val[0].extnValue.data,
                         es->val[0].extnValue.length);
        if (ret != 1) {
-           free_OCSPRequest(&req);
-           return HX509_CRYPTO_INTERNAL_ERROR;
+           ret = HX509_CRYPTO_INTERNAL_ERROR;
+           goto out;
+       }
+       ret = der_copy_octet_string(nonce, &es->val[0].extnValue);
+       if (ret) {
+           ret = ENOMEM;
+           goto out;
        }
     }
 
@@ -855,12 +1034,15 @@ hx509_ocsp_request(hx509_context context,
                       &req, &size, ret);
     free_OCSPRequest(&req);
     if (ret)
-       return ret;
+       goto out;
     if (size != request->length)
        _hx509_abort("internal ASN.1 encoder error");
 
-
     return 0;
+
+out:
+    free_OCSPRequest(&req);
+    return ret;
 }
 
 static char *
@@ -872,6 +1054,18 @@ printable_time(time_t t)
     return s;
 }
 
+/**
+ * Print the OCSP reply stored in a file.
+ *
+ * @param context a hx509 context
+ * @param path path to a file with a OCSP reply
+ * @param out the out FILE descriptor to print the reply on
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_revoke
+ */
+
 int
 hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
 {
@@ -959,10 +1153,23 @@ hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
     return ret;
 }
 
-/*
- * Verify that the `cert' is part of the OCSP reply and its not
- * expired. Doesn't verify signature the OCSP reply or its done by a
+/**
+ * Verify that the certificate is part of the OCSP reply and it's not
+ * expired. Doesn't verify signature the OCSP reply or it's done by a
  * authorized sender, that is assumed to be already done.
+ *
+ * @param context a hx509 context
+ * @param now the time right now, if 0, use the current time.
+ * @param cert the certificate to verify
+ * @param flags flags control the behavior
+ * @param data pointer to the encode ocsp reply
+ * @param length the length of the encode ocsp reply
+ * @param expiration return the time the OCSP will expire and need to
+ * be rechecked.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
  */
 
 int
@@ -1062,6 +1269,17 @@ struct hx509_crl {
     time_t expire;
 };
 
+/**
+ * Create a CRL context. Use hx509_crl_free() to free the CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl return pointer to a newly allocated CRL context.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
 int
 hx509_crl_alloc(hx509_context context, hx509_crl *crl)
 {
@@ -1083,6 +1301,18 @@ hx509_crl_alloc(hx509_context context, hx509_crl *crl)
     return ret;
 }
 
+/**
+ * Add revoked certificate to an CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl the CRL to add the revoked certificate to.
+ * @param certs keyset of certificate to revoke.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
 int
 hx509_crl_add_revoked_certs(hx509_context context,
                            hx509_crl crl, 
@@ -1091,6 +1321,19 @@ hx509_crl_add_revoked_certs(hx509_context context,
     return hx509_certs_merge(context, crl->revoked, certs);
 }
 
+/**
+ * Set the lifetime of a CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl a CRL context
+ * @param delta delta time the certificate is valid, library adds the
+ * current time to this.
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
+
 int
 hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
 {
@@ -1098,6 +1341,14 @@ hx509_crl_lifetime(hx509_context context, hx509_crl crl, int delta)
     return 0;
 }
 
+/**
+ * Free a CRL context.
+ *
+ * @param context a hx509 context.
+ * @param crl a CRL context to free.
+ *
+ * @ingroup hx509_verify
+ */
 
 void
 hx509_crl_free(hx509_context context, hx509_crl *crl)
@@ -1144,6 +1395,19 @@ add_revoked(hx509_context context, void *ctx, hx509_cert cert)
     return 0;
 }    
 
+/**
+ * Sign a CRL and return an encode certificate.
+ *
+ * @param context a hx509 context.
+ * @param signer certificate to sign the CRL with
+ * @param crl the CRL to sign
+ * @param os return the signed and encoded CRL, free with
+ * free_heim_octet_string()
+ *
+ * @return An hx509 error code, see hx509_get_error_string().
+ *
+ * @ingroup hx509_verify
+ */
 
 int
 hx509_crl_sign(hx509_context context,
index 999ce7f120408094beff45d5367f763ee8f0d244..775239cf6dfb2dc035be1bfea1f57e73180d3799 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -37,7 +37,7 @@
 #include <dlfcn.h>
 #endif
 
-RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $");
+RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $");
 
 /* XXX should we fetch these for each open ? */
 static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER;
@@ -188,11 +188,10 @@ make_cred_from_ccred(krb5_context context,
        ;
     
     if (i) {
-       cred->authdata.val = malloc(sizeof(cred->authdata.val[0]) * i);
+       cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0]));
        if (cred->authdata.val == NULL)
            goto nomem;
        cred->authdata.len = i;
-       memset(cred->authdata.val, 0, sizeof(cred->authdata.val[0]) * i);
        for (i = 0; i < cred->authdata.len; i++) {
            cred->authdata.val[i].ad_type = incred->authdata[i]->type;
            ret = krb5_data_copy(&cred->authdata.val[i].ad_data,
@@ -207,11 +206,10 @@ make_cred_from_ccred(krb5_context context,
        ;
     
     if (i) {
-       cred->addresses.val = malloc(sizeof(cred->addresses.val[0]) * i);
+       cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0]));
        if (cred->addresses.val == NULL)
            goto nomem;
        cred->addresses.len = i;
-       memset(cred->addresses.val, 0, sizeof(cred->addresses.val[0]) * i);
        
        for (i = 0; i < cred->addresses.len; i++) {
            cred->addresses.val[i].addr_type = incred->addresses[i]->type;
@@ -260,7 +258,7 @@ nomem:
     krb5_set_error_string(context, "malloc - out of memory");
     
 fail:
-    krb5_free_creds_contents(context, cred);
+    krb5_free_cred_contents(context, cred);
     return ret;
 }
 
@@ -331,6 +329,10 @@ make_ccred_from_cred(krb5_context context,
     for (i = 0; i < incred->addresses.len; i++) {
        cc_data *addr;
        addr = malloc(sizeof(*addr));
+       if (addr == NULL) {
+           ret = ENOMEM;
+           goto fail;
+       }
        addr->type = incred->addresses.val[i].addr_type;
        addr->length = incred->addresses.val[i].address.length;
        addr->data = malloc(addr->length);
@@ -383,20 +385,21 @@ fail:
     return ret;
 }
 
-static char *
-get_cc_name(cc_ccache_t cache)
+static cc_int32
+get_cc_name(krb5_acc *a)
 {
     cc_string_t name;
     cc_int32 error;
-    char *str;
 
-    error = (*cache->func->get_name)(cache, &name);
+    error = (*a->ccache->func->get_name)(a->ccache, &name);
     if (error)
-       return NULL;
+       return error;
 
-    str = strdup(name->data);
+    a->cache_name = strdup(name->data);
     (*name->func->release)(name);
-    return str;
+    if (a->cache_name == NULL)
+       return ccErrNoMem;
+    return ccNoError;
 }
 
 
@@ -405,17 +408,36 @@ acc_get_name(krb5_context context,
             krb5_ccache id)
 {
     krb5_acc *a = ACACHE(id);
-    static char n[255];
-    char *name;
+    int32_t error;
 
-    name = get_cc_name(a->ccache);
-    if (name == NULL) {
-       krb5_set_error_string(context, "malloc: out of memory");
-       return NULL;
-    }
-    strlcpy(n, name, sizeof(n));
-    free(name);
-    return n;
+    if (a->cache_name == NULL) {
+       krb5_error_code ret;
+       krb5_principal principal;
+       char *name;
+
+       ret = _krb5_get_default_principal_local(context, &principal);
+       if (ret)
+           return NULL;
+
+       ret = krb5_unparse_name(context, principal, &name);
+       krb5_free_principal(context, principal);
+       if (ret)
+           return NULL;
+
+       error = (*a->context->func->create_new_ccache)(a->context,
+                                                      cc_credentials_v5,
+                                                      name,
+                                                      &a->ccache);
+       krb5_xfree(name);
+       if (error)
+           return NULL;
+
+       error = get_cc_name(a);
+       if (error)
+           return NULL;
+    }    
+
+    return a->cache_name;
 }
 
 static krb5_error_code
@@ -448,23 +470,6 @@ acc_alloc(krb5_context context, krb5_ccache *id)
     return 0;
 }
 
-static krb5_error_code
-get_default_principal(krb5_context context, char **p)
-{
-    krb5_error_code ret;
-    krb5_principal principal;
-
-    *p = NULL;
-
-    ret = _krb5_get_default_principal_local(context, &principal);
-    if (ret)
-       return ret;
-
-    ret = krb5_unparse_name(context, principal, p);
-    krb5_free_principal(context, principal);
-    return ret;
-}
-
 static krb5_error_code
 acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
 {
@@ -478,38 +483,22 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res)
 
     a = ACACHE(*id);
 
-    if (res == NULL || res[0] == '\0') {    
-       error = (*a->context->func->open_default_ccache)(a->context,
-                                                        &a->ccache);
-       if (error == ccErrCCacheNotFound) {
-           char *p;
-
-           ret = get_default_principal(context, &p);
-           if (ret == 0) {
-               error = (*a->context->func->create_default_ccache)(a->context,
-                                                                  cc_credentials_v5,
-                                                                  p,
-                                                                  &a->ccache);
-               free(p);
-           }
+    error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
+    if (error == ccNoError) {
+       error = get_cc_name(a);
+       if (error != ccNoError) {
+           acc_close(context, *id);
+           *id = NULL;
+           return translate_cc_error(context, error);
        }
-       if (error == 0)
-           a->cache_name = get_cc_name(a->ccache);
+    } else if (error == ccErrCCacheNotFound) {
+       a->ccache = NULL;
+       a->cache_name = NULL;
+       error = 0;
     } else {
-       error = (*a->context->func->open_ccache)(a->context, res, &a->ccache);
-       if (error == 0)
-           a->cache_name = strdup(res);
-    }
-    if (error != 0) {
        *id = NULL;
        return translate_cc_error(context, error);
     }
-    if (a->cache_name == NULL) {
-       acc_close(context, *id);
-       *id = NULL;
-       krb5_set_error_string(context, "malloc: out of memory");
-       return ENOMEM;
-    }
 
     return 0;
 }
@@ -518,35 +507,17 @@ static krb5_error_code
 acc_gen_new(krb5_context context, krb5_ccache *id)
 {
     krb5_error_code ret;
-    cc_int32 error;
     krb5_acc *a;
-    char *p;
-
-    ret = get_default_principal(context, &p);
 
     ret = acc_alloc(context, id);
-    if (ret) {
-       free(p);
+    if (ret)
        return ret;
-    }
 
     a = ACACHE(*id);
 
-    error = (*a->context->func->create_new_ccache)(a->context,
-                                                  cc_credentials_v5,
-                                                  p, &a->ccache);
-    free(p);
-    if (error) {
-       *id = NULL;
-       return translate_cc_error(context, error);
-    }
-    a->cache_name = get_cc_name(a->ccache);
-    if (a->cache_name == NULL) {
-       acc_close(context, *id);
-       *id = NULL;
-       krb5_set_error_string(context, "malloc: out of memory");
-       return ENOMEM;
-    }  
+    a->ccache = NULL;
+    a->cache_name = NULL;
+
     return 0;
 }
 
@@ -555,9 +526,7 @@ acc_initialize(krb5_context context,
               krb5_ccache id,
               krb5_principal primary_principal)
 {
-    cc_credentials_iterator_t iter;
     krb5_acc *a = ACACHE(id);
-    cc_credentials_t ccred;
     krb5_error_code ret;
     int32_t error;
     char *name;
@@ -566,12 +535,17 @@ acc_initialize(krb5_context context,
     if (ret)
        return ret;
 
-    if (a->ccache == NULL) {
+    if (a->cache_name == NULL) {
        error = (*a->context->func->create_new_ccache)(a->context,
                                                       cc_credentials_v5,
                                                       name,
                                                       &a->ccache);
-    } else {    
+       free(name);
+       if (error == ccNoError)
+           error = get_cc_name(a);
+    } else {
+       cc_credentials_iterator_t iter;
+       cc_credentials_t ccred;
 
        error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
        if (error) {
@@ -593,8 +567,6 @@ acc_initialize(krb5_context context,
                                                  name);
     }
 
-    free(name);
-
     return translate_cc_error(context, error);
 }
 
@@ -629,6 +601,10 @@ acc_destroy(krb5_context context,
        error = (*a->ccache->func->destroy)(a->ccache);
        a->ccache = NULL;
     }
+    if (a->context) {
+       error = (a->context->func->release)(a->context);
+       a->context = NULL;
+    }
     return translate_cc_error(context, error);
 }
 
@@ -643,6 +619,11 @@ acc_store_cred(krb5_context context,
     krb5_error_code ret;
     cc_int32 error;
     
+    if (a->ccache == NULL) {
+       krb5_set_error_string(context, "No API credential found");
+       return KRB5_CC_NOTFOUND;
+    }
+
     cred.version = cc_credentials_v5;
     cred.credentials.credentials_v5 = &v5cred;
 
@@ -671,8 +652,10 @@ acc_get_principal(krb5_context context,
     int32_t error;
     cc_string_t name;
 
-    if (a->ccache == NULL)
-       return ENOENT;
+    if (a->ccache == NULL) {
+       krb5_set_error_string(context, "No API credential found");
+       return KRB5_CC_NOTFOUND;
+    }
 
     error = (*a->ccache->func->get_principal)(a->ccache,
                                              cc_credentials_v5,
@@ -695,6 +678,11 @@ acc_get_first (krb5_context context,
     krb5_acc *a = ACACHE(id);
     int32_t error;
     
+    if (a->ccache == NULL) {
+       krb5_set_error_string(context, "No API credential found");
+       return KRB5_CC_NOTFOUND;
+    }
+
     error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter);
     if (error) {
        krb5_clear_error_string(context);
@@ -755,6 +743,11 @@ acc_remove_cred(krb5_context context,
     cc_int32 error;
     char *client, *server;
     
+    if (a->ccache == NULL) {
+       krb5_set_error_string(context, "No API credential found");
+       return KRB5_CC_NOTFOUND;
+    }
+
     if (cred->client) {
        ret = krb5_unparse_name(context, cred->client, &client);
        if (ret)
@@ -894,12 +887,11 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
     a = ACACHE(*id);
     a->ccache = cache;
 
-    a->cache_name = get_cc_name(a->ccache);
-    if (a->cache_name == NULL) {
+    error = get_cc_name(a);
+    if (error) {
        acc_close(context, *id);
        *id = NULL;
-       krb5_set_error_string(context, "malloc: out of memory");
-       return ENOMEM;
+       return translate_cc_error(context, error);
     }  
     return 0;
 }
@@ -917,6 +909,76 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
     return 0;
 }
 
+static krb5_error_code
+acc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+    krb5_acc *afrom = ACACHE(from);
+    krb5_acc *ato = ACACHE(to);
+    int32_t error;
+
+    if (ato->ccache == NULL) {
+       cc_string_t name;
+
+       error = (*afrom->ccache->func->get_principal)(afrom->ccache,
+                                                     cc_credentials_v5,
+                                                     &name);
+       if (error)
+           return translate_cc_error(context, error);
+    
+       error = (*ato->context->func->create_new_ccache)(ato->context,
+                                                        cc_credentials_v5,
+                                                        name->data,
+                                                        &ato->ccache);
+       (*name->func->release)(name);
+       if (error)
+           return translate_cc_error(context, error);
+    }
+
+
+    error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache);
+    return translate_cc_error(context, error);
+}
+
+static krb5_error_code
+acc_default_name(krb5_context context, char **str)
+{
+    krb5_error_code ret;
+    cc_context_t cc;
+    cc_string_t name;
+    int32_t error;
+
+    ret = init_ccapi(context);
+    if (ret)
+       return ret;
+
+    error = (*init_func)(&cc, ccapi_version_3, NULL, NULL);
+    if (error)
+       return translate_cc_error(context, error);
+
+    error = (*cc->func->get_default_ccache_name)(cc, &name);
+    if (error) {
+       (*cc->func->release)(cc);
+       return translate_cc_error(context, error);
+    }
+       
+    asprintf(str, "API:%s", name->data);
+    (*name->func->release)(name);
+    (*cc->func->release)(cc);
+
+    if (*str == NULL) {
+       krb5_set_error_string(context, "out of memory");
+       return ENOMEM;
+    }
+    return 0;
+}
+
+
+/**
+ * Variable containing the API based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
 const krb5_cc_ops krb5_acc_ops = {
     "API",
     acc_get_name,
@@ -936,5 +998,7 @@ const krb5_cc_ops krb5_acc_ops = {
     acc_get_version,
     acc_get_cache_first,
     acc_get_cache_next,
-    acc_end_cache_get
+    acc_end_cache_get,
+    acc_move,
+    acc_default_name
 };
index a6005c685903718938abb0b8021eefad3953e2ea..5455d8ac9948636f0a07b6db5b00b99d04630db2 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: add_et_list.c 13713 2004-04-13 14:33:45Z lha $");
+RCSID("$Id: add_et_list.c 22603 2008-02-21 18:44:57Z lha $");
 
-/*
+/**
  * Add a specified list of error messages to the et list in context.
  * Call func (probably a comerr-generated function) with a pointer to
  * the current et_list.
+ *
+ * @param context A kerberos context.
+ * @param func The generated com_err et function.
+ *
+ * @return Returns 0 to indicate success.  Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index 8c3184305817f208ac8893376ff141c7e7c8578a..f364f5974d479869a009ec8bd2bed65026a3b351 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: addr_families.c 18805 2006-10-22 06:54:00Z lha $");
+RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $");
 
 struct addr_operations {
     int af;
@@ -767,6 +767,19 @@ find_atype(int atype)
     return NULL;
 }
 
+/**
+ * krb5_sockaddr2address stores a address a "struct sockaddr" sa in
+ * the krb5_address addr. 
+ *
+ * @param context a Keberos context
+ * @param sa a struct sockaddr to extract the address from
+ * @param addr an Kerberos 5 address to store the address in.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_sockaddr2address (krb5_context context,
                       const struct sockaddr *sa, krb5_address *addr)
@@ -780,6 +793,20 @@ krb5_sockaddr2address (krb5_context context,
     return (*a->sockaddr2addr)(sa, addr);
 }
 
+/**
+ * krb5_sockaddr2port extracts a port (if possible) from a "struct
+ * sockaddr.
+ *
+ * @param context a Keberos context
+ * @param sa a struct sockaddr to extract the port from
+ * @param port a pointer to an int16_t store the port in.
+ *
+ * @return Return an error code or 0. Will return
+ * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_sockaddr2port (krb5_context context,
                    const struct sockaddr *sa, int16_t *port)
@@ -793,6 +820,27 @@ krb5_sockaddr2port (krb5_context context,
     return (*a->sockaddr2port)(sa, port);
 }
 
+/**
+ * krb5_addr2sockaddr sets the "struct sockaddr sockaddr" from addr
+ * and port. The argument sa_size should initially contain the size of
+ * the sa and after the call, it will contain the actual length of the
+ * address. In case of the sa is too small to fit the whole address,
+ * the up to *sa_size will be stored, and then *sa_size will be set to
+ * the required length.
+ *
+ * @param context a Keberos context
+ * @param addr the address to copy the from
+ * @param sa the struct sockaddr that will be filled in
+ * @param sa_size pointer to length of sa, and after the call, it will
+ * contain the actual length of the address.
+ * @param port set port in sa.
+ *
+ * @return Return an error code or 0. Will return
+ * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_addr2sockaddr (krb5_context context,
                    const krb5_address *addr,
@@ -808,7 +856,8 @@ krb5_addr2sockaddr (krb5_context context,
        return KRB5_PROG_ATYPE_NOSUPP;
     }
     if (a->addr2sockaddr == NULL) {
-       krb5_set_error_string (context, "Can't convert address type %d to sockaddr",
+       krb5_set_error_string (context,
+                              "Can't convert address type %d to sockaddr",
                               addr->addr_type);
        return KRB5_PROG_ATYPE_NOSUPP;
     }
@@ -816,6 +865,15 @@ krb5_addr2sockaddr (krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_max_sockaddr_size returns the max size of the .Li struct
+ * sockaddr that the Kerberos library will return.
+ *
+ * @return Return an size_t of the maximum struct sockaddr.
+ *
+ * @ingroup krb5_address
+ */
+
 size_t KRB5_LIB_FUNCTION
 krb5_max_sockaddr_size (void)
 {
@@ -828,6 +886,18 @@ krb5_max_sockaddr_size (void)
     return max_sockaddr_size;
 }
 
+/**
+ * krb5_sockaddr_uninteresting returns TRUE for all .Fa sa that the
+ * kerberos library thinks are uninteresting.  One example are link
+ * local addresses.
+ *
+ * @param sa pointer to struct sockaddr that might be interesting.
+ *
+ * @return Return a non zero for uninteresting addresses.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_sockaddr_uninteresting(const struct sockaddr *sa)
 {
@@ -837,6 +907,25 @@ krb5_sockaddr_uninteresting(const struct sockaddr *sa)
     return (*a->uninteresting)(sa);
 }
 
+/**
+ * krb5_h_addr2sockaddr initializes a "struct sockaddr sa" from af and
+ * the "struct hostent" (see gethostbyname(3) ) h_addr_list
+ * component. The argument sa_size should initially contain the size
+ * of the sa, and after the call, it will contain the actual length of
+ * the address.
+ *
+ * @param context a Keberos context
+ * @param af addresses
+ * @param addr address
+ * @param sa returned struct sockaddr
+ * @param sa_size size of sa
+ * @param port port to set in sa.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_h_addr2sockaddr (krb5_context context,
                      int af,
@@ -853,6 +942,20 @@ krb5_h_addr2sockaddr (krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_h_addr2addr works like krb5_h_addr2sockaddr with the exception
+ * that it operates on a krb5_address instead of a struct sockaddr.
+ *
+ * @param context a Keberos context
+ * @param af address family
+ * @param haddr host address from struct hostent.
+ * @param addr returned krb5_address.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_h_addr2addr (krb5_context context,
                  int af,
@@ -866,6 +969,23 @@ krb5_h_addr2addr (krb5_context context,
     return (*a->h_addr2addr)(haddr, addr);
 }
 
+/**
+ * krb5_anyaddr fills in a "struct sockaddr sa" that can be used to
+ * bind(2) to.  The argument sa_size should initially contain the size
+ * of the sa, and after the call, it will contain the actual length
+ * of the address.
+ *
+ * @param context a Keberos context
+ * @param af address family
+ * @param sa sockaddr
+ * @param sa_size lenght of sa.
+ * @param port for to fill into sa.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_anyaddr (krb5_context context,
              int af,
@@ -884,6 +1004,22 @@ krb5_anyaddr (krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_print_address prints the address in addr to the string string
+ * that have the length len. If ret_len is not NULL, it will be filled
+ * with the length of the string if size were unlimited (not including
+ * the final NUL) .
+ *
+ * @param addr address to be printed
+ * @param str pointer string to print the address into
+ * @param len length that will fit into area pointed to by "str".
+ * @param ret_len return length the str.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_print_address (const krb5_address *addr, 
                    char *str, size_t len, size_t *ret_len)
@@ -921,6 +1057,19 @@ krb5_print_address (const krb5_address *addr,
     return 0;
 }
 
+/**
+ * krb5_parse_address returns the resolved hostname in string to the
+ * krb5_addresses addresses .
+ *
+ * @param context a Keberos context
+ * @param string
+ * @param addresses
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_parse_address(krb5_context context,
                   const char *string,
@@ -980,6 +1129,21 @@ krb5_parse_address(krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_address_order compares the addresses addr1 and addr2 so that
+ * it can be used for sorting addresses. If the addresses are the same
+ * address krb5_address_order will return 0. Behavies like memcmp(2). 
+ *
+ * @param context a Keberos context
+ * @param addr1 krb5_address to compare
+ * @param addr2 krb5_address to compare
+ *
+ * @return < 0 if address addr1 in "less" then addr2. 0 if addr1 and
+ * addr2 is the same address, > 0 if addr2 is "less" then addr1.
+ *
+ * @ingroup krb5_address
+ */
+
 int KRB5_LIB_FUNCTION
 krb5_address_order(krb5_context context,
                   const krb5_address *addr1,
@@ -1014,6 +1178,19 @@ krb5_address_order(krb5_context context,
                   addr1->address.length);
 }
 
+/**
+ * krb5_address_compare compares the addresses  addr1 and addr2.
+ * Returns TRUE if the two addresses are the same.
+ *
+ * @param context a Keberos context
+ * @param addr1 address to compare
+ * @param addr2 address to compare
+ *
+ * @return Return an TRUE is the address are the same FALSE if not
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_address_compare(krb5_context context,
                     const krb5_address *addr1,
@@ -1022,6 +1199,19 @@ krb5_address_compare(krb5_context context,
     return krb5_address_order (context, addr1, addr2) == 0;
 }
 
+/**
+ * krb5_address_search checks if the address addr is a member of the
+ * address set list addrlist .
+ *
+ * @param context a Keberos context.
+ * @param addr address to search for.
+ * @param addrlist list of addresses to look in for addr.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_address_search(krb5_context context,
                    const krb5_address *addr,
@@ -1035,6 +1225,18 @@ krb5_address_search(krb5_context context,
     return FALSE;
 }
 
+/**
+ * krb5_free_address frees the data stored in the address that is
+ * alloced with any of the krb5_address functions.
+ *
+ * @param context a Keberos context
+ * @param address addresss to be freed.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_address(krb5_context context,
                  krb5_address *address)
@@ -1047,6 +1249,18 @@ krb5_free_address(krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_free_addresses frees the data stored in the address that is
+ * alloced with any of the krb5_address functions.
+ *
+ * @param context a Keberos context
+ * @param addresses addressses to be freed.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_addresses(krb5_context context,
                    krb5_addresses *addresses)
@@ -1060,6 +1274,19 @@ krb5_free_addresses(krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_copy_address copies the content of address
+ * inaddr to outaddr.
+ *
+ * @param context a Keberos context
+ * @param inaddr pointer to source address
+ * @param outaddr pointer to destination address
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_address(krb5_context context,
                  const krb5_address *inaddr,
@@ -1071,6 +1298,19 @@ krb5_copy_address(krb5_context context,
     return copy_HostAddress(inaddr, outaddr);
 }
 
+/**
+ * krb5_copy_addresses copies the content of addresses
+ * inaddr to outaddr.
+ *
+ * @param context a Keberos context
+ * @param inaddr pointer to source addresses
+ * @param outaddr pointer to destination addresses
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_addresses(krb5_context context,
                    const krb5_addresses *inaddr,
@@ -1085,6 +1325,19 @@ krb5_copy_addresses(krb5_context context,
     return 0;
 }
 
+/**
+ * krb5_append_addresses adds the set of addresses in source to
+ * dest. While copying the addresses, duplicates are also sorted out.
+ *
+ * @param context a Keberos context
+ * @param dest destination of copy operation
+ * @param source adresses that are going to be added to dest
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_append_addresses(krb5_context context,
                      krb5_addresses *dest,
@@ -1115,8 +1368,17 @@ krb5_append_addresses(krb5_context context,
     return 0;
 }
 
-/*
+/**
  * Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port)
+ *
+ * @param context a Keberos context
+ * @param res built address from addr/port
+ * @param addr address to use
+ * @param port port to use
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -1170,9 +1432,19 @@ krb5_make_addrport (krb5_context context,
     return 0;
 }
 
-/*
+/**
  * Calculate the boundary addresses of `inaddr'/`prefixlen' and store
  * them in `low' and `high'.
+ *
+ * @param context a Keberos context
+ * @param inaddr address in prefixlen that the bondery searched
+ * @param prefixlen width of boundery
+ * @param low lowest address
+ * @param high highest address
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_address
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index 6b7d40d4537fbc148edca3333cdbc464879994c7..b3f775b4bea300d3ccce7fa4e64017cea20c02b6 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: asn1_glue.c 18269 2006-10-06 17:02:48Z lha $");
+RCSID("$Id: asn1_glue.c 21745 2007-07-31 16:11:25Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principal2principalname (PrincipalName *p,
@@ -53,8 +53,12 @@ _krb5_principalname2krb5_principal (krb5_context context,
                                    const Realm realm)
 {
     krb5_principal p = malloc(sizeof(*p));
+    if (p == NULL)
+       return ENOMEM;
     copy_PrincipalName(&from, &p->name);
     p->realm = strdup(realm);
+    if (p->realm == NULL)
+       return ENOMEM;
     *principal = p;
     return 0;
 }
index 5e08f15ad46102957b810ae7cc363f636f90f256..323f17a24534edd229ebdc6e1577bc166ef1dfb8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: auth_context.c 14452 2005-01-05 02:34:08Z lukeh $");
+RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_auth_con_init(krb5_context context,
@@ -141,14 +141,16 @@ krb5_auth_con_setaddrs(krb5_context context,
        if (auth_context->local_address)
            krb5_free_address (context, auth_context->local_address);
        else
-           auth_context->local_address = malloc(sizeof(krb5_address));
+           if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL)
+               return ENOMEM;
        krb5_copy_address(context, local_addr, auth_context->local_address);
     }
     if (remote_addr) {
        if (auth_context->remote_address)
            krb5_free_address (context, auth_context->remote_address);
        else
-           auth_context->remote_address = malloc(sizeof(krb5_address));
+           if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL)
+               return ENOMEM;
        krb5_copy_address(context, remote_addr, auth_context->remote_address);
     }
     return 0;
index 59aae40d2896cce50b9d22a3c24c84c128c0fa8c..5db6d2b2cf8a9c51e358e4dcce68f02eb8c4a6e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "krb5_locl.h"
 
-RCSID("$Id: cache.c 21498 2007-07-11 09:41:43Z lha $");
+RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $");
 
-/*
+/**
  * Add a new ccache type with operations `ops', overwriting any
  * existing one if `override'.
- * Return an error code or 0.
+ *
+ * @param context a Keberos context
+ * @param ops type of plugin symbol
+ * @param override flag to select if the registration is to overide
+ * an existing ops with the same name.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_ccache
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -101,8 +109,7 @@ _krb5_cc_allocate(krb5_context context,
 
 /*
  * Allocate memory for a new ccache in `id' with operations `ops'
- * and name `residual'.
- * Return 0 or an error code.
+ * and name `residual'. Return 0 or an error code.
  */
 
 static krb5_error_code
@@ -122,12 +129,21 @@ allocate_ccache (krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Find and allocate a ccache in `id' from the specification in `residual'.
  * If the ccache name doesn't contain any colon, interpret it as a file name.
- * Return 0 or an error code.
+ *
+ * @param context a Keberos context.
+ * @param name string name of a credential cache.
+ * @param id return pointer to a found credential cache.
+ *
+ * @return Return 0 or an error code. In case of an error, id is set
+ * to NULL.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_resolve(krb5_context context,
                const char *name,
@@ -135,6 +151,8 @@ krb5_cc_resolve(krb5_context context,
 {
     int i;
 
+    *id = NULL;
+
     for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) {
        size_t prefix_len = strlen(context->cc_ops[i].prefix);
 
@@ -153,57 +171,64 @@ krb5_cc_resolve(krb5_context context,
     }
 }
 
-/*
+/**
  * Generate a new ccache of type `ops' in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_gen_new(krb5_context context,
                const krb5_cc_ops *ops,
                krb5_ccache *id)
 {
-    krb5_error_code ret;
-
-    ret = _krb5_cc_allocate(context, ops, id);
-    if (ret)
-       return ret;
-    return (*id)->ops->gen_new(context, id);
+    return krb5_cc_new_unique(context, ops->prefix, NULL, id);
 }
 
-/*
+/**
  * Generates a new unique ccache of `type` in `id'. If `type' is NULL,
  * the library chooses the default credential cache type. The supplied
  * `hint' (that can be NULL) is a string that the credential cache
  * type can use to base the name of the credential on, this is to make
- * its easier for the user to differentiate the credentials.
+ * it easier for the user to differentiate the credentials.
+ *
+ * @return Returns 0 or an error code.
  *
- *  Returns 0 or an error code.
+ * @ingroup krb5_ccache
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_new_unique(krb5_context context, const char *type, 
                   const char *hint, krb5_ccache *id)
 {
-    const krb5_cc_ops *ops;
-
-    if (type == NULL)
-       type = KRB5_DEFAULT_CCNAME;
+    const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+    krb5_error_code ret;
 
-    ops = krb5_cc_get_prefix_ops(context, type);
-    if (ops == NULL) {
-       krb5_set_error_string(context, "Credential cache type %s is unknown",
-                             type);
-       return KRB5_CC_UNKNOWN_TYPE;
+    if (type) {
+       ops = krb5_cc_get_prefix_ops(context, type);
+       if (ops == NULL) {
+           krb5_set_error_string(context,
+                                 "Credential cache type %s is unknown", type);
+           return KRB5_CC_UNKNOWN_TYPE;
+       }
     }
 
-    return krb5_cc_gen_new(context, ops, id);
+    ret = _krb5_cc_allocate(context, ops, id);
+    if (ret)
+       return ret;
+    return (*id)->ops->gen_new(context, id);
 }
 
-/*
+/**
  * Return the name of the ccache `id'
+ *
+ * @ingroup krb5_ccache
  */
 
+
 const char* KRB5_LIB_FUNCTION
 krb5_cc_get_name(krb5_context context,
                 krb5_ccache id)
@@ -211,10 +236,13 @@ krb5_cc_get_name(krb5_context context,
     return id->ops->get_name(context, id);
 }
 
-/*
+/**
  * Return the type of the ccache `id'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 const char* KRB5_LIB_FUNCTION
 krb5_cc_get_type(krb5_context context,
                 krb5_ccache id)
@@ -222,12 +250,15 @@ krb5_cc_get_type(krb5_context context,
     return id->ops->prefix;
 }
 
-/*
+/**
  * Return the complete resolvable name the ccache `id' in `str´.
  * `str` should be freed with free(3).
  * Returns 0 or an error (and then *str is set to NULL).
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_get_full_name(krb5_context context,
                      krb5_ccache id,
@@ -257,10 +288,13 @@ krb5_cc_get_full_name(krb5_context context,
     return 0;
 }
 
-/*
+/**
  * Return krb5_cc_ops of a the ccache `id'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 const krb5_cc_ops *
 krb5_cc_get_ops(krb5_context context, krb5_ccache id)
 {
@@ -348,6 +382,10 @@ environment_changed(krb5_context context)
 {
     const char *e;
 
+    /* if the cc name was set, don't change it */
+    if (context->default_cc_name_set)
+       return 0;
+
     if(issuid())
        return 0;
 
@@ -367,10 +405,13 @@ environment_changed(krb5_context context)
     return 0;
 }
 
-/*
+/**
  * Set the default cc name for `context' to `name'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_set_default_name(krb5_context context, const char *name)
 {
@@ -392,14 +433,23 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
        if (e == NULL) {
            e = krb5_config_get_string(context, NULL, "libdefaults",
                                       "default_cc_name", NULL);
-           if (e == NULL)
-               e = KRB5_DEFAULT_CCNAME;
-           ret = _krb5_expand_default_cc_name(context, e, &p);
-           if (ret)
-               return ret;
+           if (e) {
+               ret = _krb5_expand_default_cc_name(context, e, &p);
+               if (ret)
+                   return ret;
+           }
+           if (e == NULL) {
+               const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE;
+               ret = (*ops->default_name)(context, &p);
+               if (ret)
+                   return ret;
+           }
        }
-    } else
+       context->default_cc_name_set = 0;
+    } else {
        p = strdup(name);
+       context->default_cc_name_set = 1;
+    }
 
     if (p == NULL) {
        krb5_set_error_string(context, "malloc - out of memory");
@@ -414,11 +464,16 @@ krb5_cc_set_default_name(krb5_context context, const char *name)
     return ret;
 }
 
-/*
+/**
  * Return a pointer to a context static string containing the default
  * ccache name.
+ *
+ * @return String to the default credential cache name.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 const char* KRB5_LIB_FUNCTION
 krb5_cc_default_name(krb5_context context)
 {
@@ -428,11 +483,15 @@ krb5_cc_default_name(krb5_context context)
     return context->default_cc_name;
 }
 
-/*
+/**
  * Open the default ccache in `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_default(krb5_context context,
                krb5_ccache *id)
@@ -446,11 +505,15 @@ krb5_cc_default(krb5_context context,
     return krb5_cc_resolve(context, p, id);
 }
 
-/*
+/**
  * Create a new ccache in `id' for `primary_principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_initialize(krb5_context context,
                   krb5_ccache id,
@@ -460,11 +523,15 @@ krb5_cc_initialize(krb5_context context,
 }
 
 
-/*
+/**
  * Remove the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_destroy(krb5_context context,
                krb5_ccache id)
@@ -476,11 +543,15 @@ krb5_cc_destroy(krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Stop using the ccache `id' and free the related resources.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_close(krb5_context context,
              krb5_ccache id)
@@ -491,11 +562,15 @@ krb5_cc_close(krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Store `creds' in the ccache `id'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_store_cred(krb5_context context,
                   krb5_ccache id,
@@ -504,13 +579,17 @@ krb5_cc_store_cred(krb5_context context,
     return (*id->ops->store)(context, id, creds);
 }
 
-/*
+/**
  * Retrieve the credential identified by `mcreds' (and `whichfields')
  * from `id' in `creds'. 'creds' must be free by the caller using
  * krb5_free_cred_contents.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_retrieve_cred(krb5_context context,
                      krb5_ccache id,
@@ -526,7 +605,9 @@ krb5_cc_retrieve_cred(krb5_context context,
                                    mcreds, creds);
     }
 
-    krb5_cc_start_seq_get(context, id, &cursor);
+    ret = krb5_cc_start_seq_get(context, id, &cursor);
+    if (ret)
+       return ret;
     while((ret = krb5_cc_next_cred(context, id, &cursor, creds)) == 0){
        if(krb5_compare_creds(context, whichfields, mcreds, creds)){
            ret = 0;
@@ -538,11 +619,15 @@ krb5_cc_retrieve_cred(krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Return the principal of `id' in `principal'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_get_principal(krb5_context context,
                      krb5_ccache id,
@@ -551,12 +636,16 @@ krb5_cc_get_principal(krb5_context context,
     return (*id->ops->get_princ)(context, id, principal);
 }
 
-/*
+/**
  * Start iterating over `id', `cursor' is initialized to the
  * beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_start_seq_get (krb5_context context,
                       const krb5_ccache id,
@@ -565,12 +654,16 @@ krb5_cc_start_seq_get (krb5_context context,
     return (*id->ops->get_first)(context, id, cursor);
 }
 
-/*
+/**
  * Retrieve the next cred pointed to by (`id', `cursor') in `creds'
  * and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_next_cred (krb5_context context,
                   const krb5_ccache id,
@@ -580,7 +673,12 @@ krb5_cc_next_cred (krb5_context context,
     return (*id->ops->get_next)(context, id, cursor, creds);
 }
 
-/* like krb5_cc_next_cred, but allow for selective retrieval */
+/**
+ * Like krb5_cc_next_cred, but allow for selective retrieval
+ *
+ * @ingroup krb5_ccache
+ */
+
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_next_cred_match(krb5_context context,
@@ -601,10 +699,13 @@ krb5_cc_next_cred_match(krb5_context context,
     }
 }
 
-/*
+/**
  * Destroy the cursor `cursor'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_end_seq_get (krb5_context context,
                     const krb5_ccache id,
@@ -613,10 +714,13 @@ krb5_cc_end_seq_get (krb5_context context,
     return (*id->ops->end_get)(context, id, cursor);
 }
 
-/*
+/**
  * Remove the credential identified by `cred', `which' from `id'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_remove_cred(krb5_context context,
                    krb5_ccache id,
@@ -632,10 +736,13 @@ krb5_cc_remove_cred(krb5_context context,
     return (*id->ops->remove_cred)(context, id, which, cred);
 }
 
-/*
+/**
  * Set the flags of `id' to `flags'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_set_flags(krb5_context context,
                  krb5_ccache id,
@@ -644,10 +751,13 @@ krb5_cc_set_flags(krb5_context context,
     return (*id->ops->set_flags)(context, id, flags);
 }
                    
-/*
+/**
  * Copy the contents of `from' to `to'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_copy_cache_match(krb5_context context,
                         const krb5_ccache from,
@@ -689,6 +799,13 @@ krb5_cc_copy_cache_match(krb5_context context,
     return ret;
 }
 
+/**
+ * Just like krb5_cc_copy_cache_match, but copy everything.
+ *
+ * @ingroup krb5_ccache
+ */
+
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_copy_cache(krb5_context context,
                   const krb5_ccache from,
@@ -697,10 +814,13 @@ krb5_cc_copy_cache(krb5_context context,
     return krb5_cc_copy_cache_match(context, from, to, 0, NULL, NULL);
 }
 
-/*
+/**
  * Return the version of `id'.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_get_version(krb5_context context,
                    const krb5_ccache id)
@@ -711,23 +831,30 @@ krb5_cc_get_version(krb5_context context,
        return 0;
 }
 
-/*
+/**
  * Clear `mcreds' so it can be used with krb5_cc_retrieve_cred
+ *
+ * @ingroup krb5_ccache
  */
 
+
 void KRB5_LIB_FUNCTION
 krb5_cc_clear_mcred(krb5_creds *mcred)
 {
     memset(mcred, 0, sizeof(*mcred));
 }
 
-/*
+/**
  * Get the cc ops that is registered in `context' to handle the
  * `prefix'. `prefix' can be a complete credential cache name or a
  * prefix, the function will only use part up to the first colon (:)
- * if there is one.  Returns NULL if ops not found.
+ * if there is one.
+ * Returns NULL if ops not found.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 const krb5_cc_ops *
 krb5_cc_get_prefix_ops(krb5_context context, const char *prefix)
 {
@@ -761,12 +888,16 @@ struct krb5_cc_cache_cursor_data {
     krb5_cc_cursor cursor;
 };
 
-/*
+/**
  * Start iterating over all caches of `type'. If `type' is NULL, the
  * default type is * used. `cursor' is initialized to the beginning.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_cache_get_first (krb5_context context,
                         const char *type,
@@ -807,12 +938,16 @@ krb5_cc_cache_get_first (krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Retrieve the next cache pointed to by (`cursor') in `id'
  * and advance `cursor'.
- * Return 0 or an error code.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_cache_next (krb5_context context,
                   krb5_cc_cache_cursor cursor,
@@ -821,10 +956,15 @@ krb5_cc_cache_next (krb5_context context,
     return cursor->ops->get_cache_next(context, cursor->cursor, id);
 }
 
-/*
+/**
  * Destroy the cursor `cursor'.
+ *
+ * @return Return 0 or an error code.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_cache_end_seq_get (krb5_context context,
                           krb5_cc_cache_cursor cursor)
@@ -836,14 +976,18 @@ krb5_cc_cache_end_seq_get (krb5_context context,
     return ret;
 }
 
-/*
+/**
  * Search for a matching credential cache of type `type' that have the
  * `principal' as the default principal. If NULL is used for `type',
  * the default type is used. On success, `id' needs to be freed with
- * krb5_cc_close or krb5_cc_destroy. On failure, error code is
- * returned and `id' is set to NULL.
+ * krb5_cc_close or krb5_cc_destroy.
+ *
+ * @return On failure, error code is returned and `id' is set to NULL.
+ *
+ * @ingroup krb5_ccache
  */
 
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_cache_match (krb5_context context,
                     krb5_principal client,
@@ -895,3 +1039,35 @@ krb5_cc_cache_match (krb5_context context,
     return 0;
 }
 
+/**
+ * Move the content from one credential cache to another. The
+ * operation is an atomic switch. 
+ *
+ * @param context a Keberos context
+ * @param from the credential cache to move the content from
+ * @param to the credential cache to move the content to
+
+ * @return On sucess, from is freed. On failure, error code is
+ * returned and from and to are both still allocated.
+ *
+ * @ingroup krb5_ccache
+ */
+
+krb5_error_code
+krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+    krb5_error_code ret;
+
+    if (strcmp(from->ops->prefix, to->ops->prefix) != 0) {
+       krb5_set_error_string(context, "Moving credentials between diffrent "
+                             "types not yet supported");
+       return KRB5_CC_NOSUPP;
+    }
+
+    ret = (*to->ops->move)(context, from, to);
+    if (ret == 0) {
+       memset(from, 0, sizeof(*from));
+       free(from);
+    }
+    return ret;
+}
index b54e293a602a765005d95003ee6e25be45e9acc4..256783310e935026b98800427c484d52c36dd341 100644 (file)
 #include "krb5_locl.h"
 #include <com_err.h>
 
-RCSID("$Id: context.c 19107 2006-11-24 14:24:33Z lha $");
+RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $");
 
 #define INIT_FIELD(C, T, E, D, F)                                      \
     (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D),        \
                                                "libdefaults", F, NULL)
 
+#define INIT_FLAG(C, O, V, D, F)                                       \
+    do {                                                               \
+       if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \
+           (C)->O |= V;                                                \
+        }                                                              \
+    } while(0)
+
 /*
  * Set the list of etypes `ret_etypes' from the configuration variable
  * `name'
@@ -181,11 +188,28 @@ init_context_from_config_file(krb5_context context)
     INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup");
     INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc");
     INIT_FIELD(context, int, large_msg_size, 1400, "large_message_size");
-    INIT_FIELD(context, bool, dns_canonicalize_hostname, TRUE, "dns_canonicalize_hostname");
+    INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname");
+    INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac");
     context->default_cc_name = NULL;
+    context->default_cc_name_set = 0;
     return 0;
 }
 
+/**
+ * Initializes the context structure and reads the configuration file
+ * /etc/krb5.conf. The structure should be freed by calling
+ * krb5_free_context() when it is no longer being used.
+ *
+ * @param context pointer to returned context
+ *
+ * @return Returns 0 to indicate success.  Otherwise an errno code is
+ * returned.  Failure means either that something bad happened during
+ * initialization (typically ENOMEM) or that Kerberos should not be
+ * used ENXIO.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_init_context(krb5_context *context)
 {
@@ -246,11 +270,21 @@ out:
     return ret;
 }
 
+/**
+ * Frees the krb5_context allocated by krb5_init_context().
+ *
+ * @param context context to be freed.
+ *
+ *  @ingroup krb5
+*/
+
 void KRB5_LIB_FUNCTION
 krb5_free_context(krb5_context context)
 {
     if (context->default_cc_name)
        free(context->default_cc_name);
+    if (context->default_cc_name_env)
+       free(context->default_cc_name_env);
     free(context->etypes);
     free(context->etypes_des);
     krb5_free_host_realm (context, context->default_realms);
@@ -272,6 +306,18 @@ krb5_free_context(krb5_context context)
     free(context);
 }
 
+/**
+ * Reinit the context from a new set of filenames.
+ *
+ * @param context context to add configuration too.
+ * @param filenames array of filenames, end of list is indicated with a NULL filename.
+ *
+ * @return Returns 0 to indicate success.  Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_config_files(krb5_context context, char **filenames)
 {
@@ -324,7 +370,7 @@ add_file(char ***pfilenames, int *len, char *file)
 }
 
 /*
- *  `pq' isn't free, its up the the caller
+ *  `pq' isn't free, it's up the the caller
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -380,6 +426,18 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp)
     return 0;
 }
 
+/**
+ * Prepend the filename to the global configuration list.
+ *
+ * @param filelist a filename to add to the default list of filename
+ * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
+ *
+ * @return Returns 0 to indicate success.  Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
 {
@@ -399,6 +457,17 @@ krb5_prepend_config_files_default(const char *filelist, char ***pfilenames)
     return 0;
 }
 
+/**
+ * Get the global configuration list.
+ *
+ * @param pfilenames return array of filenames, should be freed with krb5_free_config_files().
+ *
+ * @return Returns 0 to indicate success.  Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION 
 krb5_get_default_config_files(char ***pfilenames)
 {
@@ -414,6 +483,17 @@ krb5_get_default_config_files(char ***pfilenames)
     return krb5_prepend_config_files(files, NULL, pfilenames);
 }
 
+/**
+ * Free a list of configuration files.
+ *
+ * @param filenames list to be freed.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_free_config_files(char **filenames)
 {
@@ -423,12 +503,17 @@ krb5_free_config_files(char **filenames)
     free(filenames);
 }
 
-/*
+/**
  * Returns the list of Kerberos encryption types sorted in order of
- * most preferred to least preferred encryption type.  The array ends
- * with ETYPE_NULL.  Note that some encryption types might be
- * disabled, so you need to check with krb5_enctype_valid() before
- * using the encryption type.
+ * most preferred to least preferred encryption type.  Note that some
+ * encryption types might be disabled, so you need to check with
+ * krb5_enctype_valid() before using the encryption type.
+ *
+ * @return list of enctypes, terminated with ETYPE_NULL. Its a static
+ * array completed into the Kerberos library so the content doesn't
+ * need to be freed.
+ *
+ * @ingroup krb5
  */
 
 const krb5_enctype * KRB5_LIB_FUNCTION
@@ -479,6 +564,19 @@ default_etypes(krb5_context context, krb5_enctype **etype)
     return 0;
 }
 
+/**
+ * Set the default encryption types that will be use in communcation
+ * with the KDC, clients and servers.
+ *
+ * @param context Kerberos 5 context.
+ * @param etypes Encryption types, array terminated with ETYPE_NULL (0).
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_default_in_tkt_etypes(krb5_context context, 
                               const krb5_enctype *etypes)
@@ -507,6 +605,19 @@ krb5_set_default_in_tkt_etypes(krb5_context context,
     return 0;
 }
 
+/**
+ * Get the default encryption types that will be use in communcation
+ * with the KDC, clients and servers.
+ *
+ * @param context Kerberos 5 context.
+ * @param etypes Encryption types, array terminated with
+ * ETYPE_NULL(0), caller should free array with krb5_xfree():
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_default_in_tkt_etypes(krb5_context context,
@@ -534,6 +645,18 @@ krb5_get_default_in_tkt_etypes(krb5_context context,
   return 0;
 }
 
+/**
+ * Return the error string for the error code. The caller must not
+ * free the string.
+ *
+ * @param context Kerberos 5 context.
+ * @param code Kerberos error code.
+ *
+ * @return the error message matching code
+ *
+ * @ingroup krb5
+ */
+
 const char* KRB5_LIB_FUNCTION
 krb5_get_err_text(krb5_context context, krb5_error_code code)
 {
@@ -547,6 +670,14 @@ krb5_get_err_text(krb5_context context, krb5_error_code code)
     return p;
 }
 
+/**
+ * Init the built-in ets in the Kerberos library. 
+ *
+ * @param context kerberos context to add the ets too
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_init_ets(krb5_context context)
 {
@@ -561,18 +692,50 @@ krb5_init_ets(krb5_context context)
     }
 }
 
+/**
+ * Make the kerberos library default to the admin KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param flag boolean flag to select if the use the admin KDC or not.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag)
 {
     context->use_admin_kdc = flag;
 }
 
+/**
+ * Make the kerberos library default to the admin KDC.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return boolean flag to telling the context will use admin KDC as the default KDC.
+ *
+ * @ingroup krb5
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_get_use_admin_kdc (krb5_context context)
 {
     return context->use_admin_kdc;
 }
 
+/**
+ * Add extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to add
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
 {
@@ -584,6 +747,19 @@ krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses)
        return krb5_set_extra_addresses(context, addresses);
 }
 
+/**
+ * Set extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to set
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
 {
@@ -607,6 +783,19 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses)
     return krb5_copy_addresses(context, addresses, context->extra_addresses);
 }
 
+/**
+ * Get extra address to the address list that the library will add to
+ * the client's address list when communicating with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to set
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
 {
@@ -617,6 +806,19 @@ krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses)
     return krb5_copy_addresses(context,context->extra_addresses, addresses);
 }
 
+/**
+ * Add extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to ignore
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
 {
@@ -628,6 +830,19 @@ krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses)
        return krb5_set_ignore_addresses(context, addresses);
 }
 
+/**
+ * Set extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses addreses to ignore
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
 {
@@ -650,6 +865,19 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses)
     return krb5_copy_addresses(context, addresses, context->ignore_addresses);
 }
 
+/**
+ * Get extra addresses to ignore when fetching addresses from the
+ * underlaying operating system.
+ *
+ * @param context Kerberos 5 context.
+ * @param addresses list addreses ignored
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
 {
@@ -660,6 +888,18 @@ krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses)
     return krb5_copy_addresses(context, context->ignore_addresses, addresses);
 }
 
+/**
+ * Set version of fcache that the library should use.
+ *
+ * @param context Kerberos 5 context.
+ * @param version version number.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_set_fcache_version(krb5_context context, int version)
 {
@@ -667,6 +907,18 @@ krb5_set_fcache_version(krb5_context context, int version)
     return 0;
 }
 
+/**
+ * Get version of fcache that the library should use.
+ *
+ * @param context Kerberos 5 context.
+ * @param version version number.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_fcache_version(krb5_context context, int *version)
 {
@@ -674,6 +926,15 @@ krb5_get_fcache_version(krb5_context context, int *version)
     return 0;
 }
 
+/**
+ * Runtime check if the Kerberos library was complied with thread support.
+ *
+ * @return TRUE if the library was compiled with thread support, FALSE if not.
+ *
+ * @ingroup krb5
+ */
+
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_is_thread_safe(void)
 {
@@ -684,18 +945,52 @@ krb5_is_thread_safe(void)
 #endif
 }
 
+/**
+ * Set if the library should use DNS to canonicalize hostnames.
+ *
+ * @param context Kerberos 5 context.
+ * @param flag if its dns canonicalizion is used or not.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag)
 {
-    context->dns_canonicalize_hostname = flag;
+    if (flag)
+       context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
+    else
+       context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME;
 }
 
+/**
+ * Get if the library uses DNS to canonicalize hostnames.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return return non zero if the library uses DNS to canonicalize hostnames.
+ *
+ * @ingroup krb5
+ */
+
 krb5_boolean KRB5_LIB_FUNCTION
 krb5_get_dns_canonicalize_hostname (krb5_context context)
 {
-    return context->dns_canonicalize_hostname;
+    return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0;
 }
 
+/**
+ * Get current offset in time to the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param sec seconds part of offset.
+ * @param usec micro seconds part of offset.
+ *
+ * @return return non zero if the library uses DNS to canonicalize hostnames.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
 {
@@ -706,12 +1001,31 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec)
     return 0;
 }
 
+/**
+ * Get max time skew allowed.
+ *
+ * @param context Kerberos 5 context.
+ *
+ * @return timeskew in seconds.
+ *
+ * @ingroup krb5
+ */
+
 time_t KRB5_LIB_FUNCTION
 krb5_get_max_time_skew (krb5_context context)
 {
     return context->max_skew;
 }
 
+/**
+ * Set max time skew allowed.
+ *
+ * @param context Kerberos 5 context.
+ * @param t timeskew in seconds.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_set_max_time_skew (krb5_context context, time_t t)
 {
index 1d1b4d70706a01a39df07fd6500fabdaeedf87f7..b2af0187eac31a3e7dcf43fa41982511f3dccc45 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: convert_creds.c 14897 2005-04-23 19:40:57Z lha $");
+RCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -42,10 +42,20 @@ check_ticket_flags(TicketFlags f)
     return 0; /* maybe add some more tests here? */
 }
 
-/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'.
- * This is done by sending them to the 524 function in the KDC.  If
+/**
+ * Convert the v5 credentials in in_cred to v4-dito in v4creds.  This
+ * is done by sending them to the 524 function in the KDC.  If
  * `in_cred' doesn't contain a DES session key, then a new one is
  * gotten from the KDC and stored in the cred cache `ccache'.
+ *
+ * @param context Kerberos 5 context.
+ * @param in_cred the credential to convert
+ * @param v4creds the converted credential
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5_v4compat
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -134,6 +144,21 @@ out2:
     return ret;
 }
 
+/**
+ * Convert the v5 credentials in in_cred to v4-dito in v4creds,
+ * check the credential cache ccache before checking with the KDC.
+ *
+ * @param context Kerberos 5 context.
+ * @param ccache credential cache used to check for des-ticket.
+ * @param in_cred the credential to convert
+ * @param v4creds the converted credential
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5_v4compat
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb524_convert_creds_kdc_ccache(krb5_context context, 
                                krb5_ccache ccache,
index 4e668c2a14f128307fc8605527c804b4368420dd..8c4f39b4ac4c0f05f3b9a3d61e5ed158fb399c95 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: copy_host_realm.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $");
 
-/*
+/**
  * Copy the list of realms from `from' to `to'.
+ *
+ * @param context Kerberos 5 context.
+ * @param from list of realms to copy from.
+ * @param to list of realms to copy to, free list of krb5_free_host_realm().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
index d4d83162f1e471073a2ce7a1be8e28cc4c80bc39..17ef46dfa3b6736f2fbf6a210910203f5cf254b7 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: creds.c 15167 2005-05-18 04:21:57Z lha $");
+RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $");
+
+#undef __attribute__
+#define __attribute__(X)
 
 /* keep this for compatibility with older code */
-krb5_error_code KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated))
 krb5_free_creds_contents (krb5_context context, krb5_creds *c)
 {
     return krb5_free_cred_contents (context, c);
 }    
 
+/**
+ * Free content of krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param c krb5_creds to free.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_cred_contents (krb5_context context, krb5_creds *c)
 {
@@ -58,6 +73,19 @@ krb5_free_cred_contents (krb5_context context, krb5_creds *c)
     return 0;
 }
 
+/**
+ * Copy content of krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param incred source credential
+ * @param c destination credential, free with krb5_free_cred_contents().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_creds_contents (krb5_context context,
                          const krb5_creds *incred,
@@ -102,6 +130,19 @@ fail:
     return ret;
 }
 
+/**
+ * Copy krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param incred source credential
+ * @param outcred destination credential, free with krb5_free_creds().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_creds (krb5_context context,
                 const krb5_creds *incred,
@@ -119,6 +160,18 @@ krb5_copy_creds (krb5_context context,
     return krb5_copy_creds_contents (context, incred, c);
 }
 
+/**
+ * Free krb5_creds.
+ *
+ * @param context Kerberos 5 context.
+ * @param c krb5_creds to free.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_free_creds (krb5_context context, krb5_creds *c)
 {
@@ -127,15 +180,7 @@ krb5_free_creds (krb5_context context, krb5_creds *c)
     return 0;
 }
 
-/* XXX these do not belong here */
-static krb5_boolean
-krb5_data_equal(const krb5_data *a, const krb5_data *b)
-{
-    if(a->length != b->length)
-       return FALSE;
-    return memcmp(a->data, b->data, a->length) == 0;
-}
-
+/* XXX this do not belong here */
 static krb5_boolean
 krb5_times_equal(const krb5_times *a, const krb5_times *b)
 {
@@ -145,9 +190,18 @@ krb5_times_equal(const krb5_times *a, const krb5_times *b)
        a->renew_till == b->renew_till;
 }
 
-/*
+/**
  * Return TRUE if `mcreds' and `creds' are equal (`whichfields'
  * determines what equal means).
+ *
+ * @param context Kerberos 5 context.
+ * @param whichfields which fields to compare.
+ * @param mcreds cred to compare with.
+ * @param creds cred to compare with.
+ *
+ * @return return TRUE if mcred and creds are equal, FALSE if not.
+ *
+ * @ingroup krb5
  */
 
 krb5_boolean KRB5_LIB_FUNCTION
@@ -201,11 +255,11 @@ krb5_compare_creds(krb5_context context, krb5_flags whichfields,
            for(i = 0; match && i < mcreds->authdata.len; i++)
                match = (mcreds->authdata.val[i].ad_type == 
                         creds->authdata.val[i].ad_type) &&
-                   krb5_data_equal(&mcreds->authdata.val[i].ad_data,
-                                   &creds->authdata.val[i].ad_data);
+                   (krb5_data_cmp(&mcreds->authdata.val[i].ad_data,
+                                  &creds->authdata.val[i].ad_data) == 0);
     }
     if (match && (whichfields & KRB5_TC_MATCH_2ND_TKT))
-       match = krb5_data_equal(&mcreds->second_ticket, &creds->second_ticket);
+       match = (krb5_data_cmp(&mcreds->second_ticket, &creds->second_ticket) == 0);
 
     if (match && (whichfields & KRB5_TC_MATCH_IS_SKEY))
        match = ((mcreds->second_ticket.length == 0) == 
index 12f75d0bcde6c656c9518fa31fa07cd49e161349..2e6349094683b7ef9a82920477906bf68ee9a498 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: crypto.c 21130 2007-06-18 20:45:21Z lha $");
+RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $");
 
 #undef CRYPTO_DEBUG
 #ifdef CRYPTO_DEBUG
@@ -184,7 +184,7 @@ krb5_DES_schedule(krb5_context context,
 #ifdef ENABLE_AFS_STRING_TO_KEY
 
 /* This defines the Andrew string_to_key function.  It accepts a password
- * string as input and converts its via a one-way encryption algorithm to a DES
+ * string as input and converts it via a one-way encryption algorithm to a DES
  * encryption key.  It is compatible with the original Andrew authentication
  * service password database.
  */
@@ -425,6 +425,7 @@ DES3_string_to_key(krb5_context context,
     size_t len;
     unsigned char tmp[24];
     DES_cblock keys[3];
+    krb5_error_code ret;
     
     len = password.length + salt.saltvalue.length;
     str = malloc(len);
@@ -439,7 +440,13 @@ DES3_string_to_key(krb5_context context,
        DES_key_schedule s[3];
        int i;
        
-       _krb5_n_fold(str, len, tmp, 24);
+       ret = _krb5_n_fold(str, len, tmp, 24);
+       if (ret) {
+           memset(str, 0, len);
+           free(str);
+           krb5_set_error_string(context, "out of memory");
+           return ret;
+       }
        
        for(i = 0; i < 3; i++){
            memcpy(keys + i, tmp + i * 8, sizeof(keys[i]));
@@ -557,12 +564,14 @@ ARCFOUR_string_to_key(krb5_context context,
     size_t len;
     int i;
     MD4_CTX m;
+    krb5_error_code ret;
 
     len = 2 * password.length;
     s = malloc (len);
     if (len != 0 && s == NULL) {
        krb5_set_error_string(context, "malloc: out of memory");
-       return ENOMEM;
+       ret = ENOMEM;
+       goto out;
     }
     for (p = s, i = 0; i < password.length; ++i) {
        *p++ = ((char *)password.data)[i];
@@ -571,11 +580,17 @@ ARCFOUR_string_to_key(krb5_context context,
     MD4_Init (&m);
     MD4_Update (&m, s, len);
     key->keytype = enctype;
-    krb5_data_alloc (&key->keyvalue, 16);
+    ret = krb5_data_alloc (&key->keyvalue, 16);
+    if (ret) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       goto out;
+    }
     MD4_Final (key->keyvalue.data, &m);
     memset (s, 0, len);
+    ret = 0;
+out:
     free (s);
-    return 0;
+    return ret;
 }
 
 /*
@@ -1829,7 +1844,9 @@ create_checksum (krb5_context context,
     } else
        dkey = NULL;
     result->cksumtype = ct->type;
-    krb5_data_alloc(&result->checksum, ct->checksumsize);
+    ret = krb5_data_alloc(&result->checksum, ct->checksumsize);
+    if (ret)
+       return (ret);
     (*ct->checksum)(context, dkey, data, len, usage, result);
     return 0;
 }
@@ -2751,6 +2768,7 @@ krb5_enctype_to_string(krb5_context context,
     if(e == NULL) {
        krb5_set_error_string (context, "encryption type %d not supported",
                               etype);
+       *string = NULL;
        return KRB5_PROG_ETYPE_NOSUPP;
     }
     *string = strdup(e->name);
@@ -3525,15 +3543,19 @@ derive_key(krb5_context context,
     ret = _key_schedule(context, key);
     if(ret)
        return ret;
-    if(et->blocksize * 8 < kt->bits || 
-       len != et->blocksize) {
+    if(et->blocksize * 8 < kt->bits || len != et->blocksize) {
        nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8);
        k = malloc(nblocks * et->blocksize);
        if(k == NULL) {
            krb5_set_error_string(context, "malloc: out of memory");
            return ENOMEM;
        }
-       _krb5_n_fold(constant, len, k, et->blocksize);
+       ret = _krb5_n_fold(constant, len, k, et->blocksize);
+       if (ret) {
+           free(k);
+           krb5_set_error_string(context, "out of memory");
+           return ret;
+       }
        for(i = 0; i < nblocks; i++) {
            if(i > 0)
                memcpy(k + i * et->blocksize, 
@@ -3559,7 +3581,12 @@ derive_key(krb5_context context,
            krb5_set_error_string(context, "malloc: out of memory");
            return ENOMEM;
        }
-       _krb5_n_fold(c, len, k, res_len);
+       ret = _krb5_n_fold(c, len, k, res_len);
+       if (ret) {
+           free(k);
+           krb5_set_error_string(context, "out of memory");
+           return ret;
+       }
        free(c);
     }
     
@@ -3821,7 +3848,12 @@ krb5_string_to_key_derived(krb5_context context,
        krb5_set_error_string (context, "malloc: out of memory");
        return ENOMEM;
     }
-    _krb5_n_fold(str, len, tmp, keylen);
+    ret = _krb5_n_fold(str, len, tmp, keylen);
+    if (ret) {
+       free(tmp);
+       krb5_set_error_string(context, "out of memory");
+       return ret;
+    }
     kd.schedule = NULL;
     DES3_postproc (context, tmp, keylen, &kd); /* XXX */
     memset(tmp, 0, keylen);
@@ -4122,7 +4154,7 @@ main()
 
     d = _new_derived_key(crypto, usage);
     if(d == NULL)
-       return ENOMEM;
+       krb5_errx(context, 1, "_new_derived_key failed");
     krb5_copy_keyblock(context, crypto->key.key, &d->key);
     _krb5_put_int(constant, usage, 4);
     derive_key(context, crypto->et, d, constant, sizeof(constant));
@@ -4148,11 +4180,10 @@ main()
        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */
     key.keyvalue.length = 4;
 
-    d = calloc(1, sizeof(*d));
-
+    d = ecalloc(1, sizeof(*d));
     d->key = &key;
     res.checksum.length = 20;
-    res.checksum.data = malloc(res.checksum.length);
+    res.checksum.data = emalloc(res.checksum.length);
     SP_HMAC_SHA1_checksum(context, d, data, 28, &res);
 
     return 0;
index 2ece85bdb322fc20874dd1f2b651315c504b32d6..eda1a8b2598b710d24757f278d317f9c588171a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "krb5_locl.h"
 
-RCSID("$Id: data.c 20039 2007-01-23 20:34:01Z lha $");
+RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $");
+
+/**
+ * Reset the (potentially uninitalized) krb5_data structure.
+ *
+ * @param p krb5_data to reset.
+ *
+ * @ingroup krb5
+ */
 
 void KRB5_LIB_FUNCTION
 krb5_data_zero(krb5_data *p)
@@ -42,6 +50,15 @@ krb5_data_zero(krb5_data *p)
     p->data   = NULL;
 }
 
+/**
+ * Free the content of krb5_data structure, its ok to free a zeroed
+ * structure. When done, the structure will be zeroed.
+ * 
+ * @param p krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_data_free(krb5_data *p)
 {
@@ -50,12 +67,30 @@ krb5_data_free(krb5_data *p)
     krb5_data_zero(p);
 }
 
+/**
+ * Same as krb5_data_free().
+ * 
+ * @param context Kerberos 5 context.
+ * @param data krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION 
 krb5_free_data_contents(krb5_context context, krb5_data *data)
 {
     krb5_data_free(data);
 }
 
+/**
+ * Free krb5_data (and its content).
+ * 
+ * @param context Kerberos 5 context.
+ * @param p krb5_data to free.
+ *
+ * @ingroup krb5
+ */
+
 void KRB5_LIB_FUNCTION
 krb5_free_data(krb5_context context,
               krb5_data *p)
@@ -64,6 +99,18 @@ krb5_free_data(krb5_context context,
     free(p);
 }
 
+/**
+ * Allocate data of and krb5_data.
+ * 
+ * @param p krb5_data to free.
+ * @param len size to allocate.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_data_alloc(krb5_data *p, int len)
 {
@@ -74,6 +121,18 @@ krb5_data_alloc(krb5_data *p, int len)
     return 0;
 }
 
+/**
+ * Grow (or shrink) the content of krb5_data to a new size.
+ * 
+ * @param p krb5_data to free.
+ * @param len new size.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_data_realloc(krb5_data *p, int len)
 {
@@ -86,6 +145,19 @@ krb5_data_realloc(krb5_data *p, int len)
     return 0;
 }
 
+/**
+ * Copy the data of len into the krb5_data.
+ * 
+ * @param p krb5_data to copy into.
+ * @param data data to copy..
+ * @param len new size.
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_data_copy(krb5_data *p, const void *data, size_t len)
 {
@@ -99,6 +171,19 @@ krb5_data_copy(krb5_data *p, const void *data, size_t len)
     return 0;
 }
 
+/**
+ * Copy the data into a newly allocated krb5_data.
+ * 
+ * @param context Kerberos 5 context.
+ * @param indata the krb5_data data to copy
+ * @param outdata new krb5_date to copy too. Free with krb5_free_data().
+ *
+ * @return Returns 0 to indicate success. Otherwise an kerberos et
+ * error code is returned.
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_copy_data(krb5_context context, 
               const krb5_data *indata, 
@@ -119,6 +204,17 @@ krb5_copy_data(krb5_context context,
     return ret;
 }
 
+/**
+ * Compare to data.
+ * 
+ * @param data1 krb5_data to compare
+ * @param data2 krb5_data to compare
+ *
+ * @return return the same way as memcmp(), useful when sorting.
+ *
+ * @ingroup krb5
+ */
+
 int KRB5_LIB_FUNCTION
 krb5_data_cmp(const krb5_data *data1, const krb5_data *data2)
 {
index c6b5cfb18bb768607bbe1ff3f4675ae8412e3a3b..19315cea86787faf9063a7c13546ca94c22feb4a 100644 (file)
 
 #include <krb5_locl.h>
 
-RCSID("$Id: eai_to_heim_errno.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: eai_to_heim_errno.c 22065 2007-11-11 16:41:06Z lha $");
 
-/*
- * convert the getaddrinfo error code in `eai_errno' into a
- * krb5_error_code. `system_error' should have the value of the errno
- * after the failed call.
+/**
+ * Convert the getaddrinfo() error code to a Kerberos et error code.
+ *
+ * @param eai_errno contains the error code from getaddrinfo().
+ * @param system_error should have the value of errno after the failed getaddrinfo().
+ *
+ * @return Kerberos error code representing the EAI errors.
+ *
+ * @ingroup krb5_error
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -78,6 +83,17 @@ krb5_eai_to_heim_errno(int eai_errno, int system_error)
     }
 }
 
+/**
+ * Convert the gethostname() error code (h_error) to a Kerberos et
+ * error code.
+ *
+ * @param eai_errno contains the error code from gethostname().
+ *
+ * @return Kerberos error code representing the gethostname errors.
+ *
+ * @ingroup krb5_error
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_h_errno_to_heim_errno(int eai_errno)
 {
index 1ba64944872cac2bf3cd61e691b4a48f61405cca..ff6e98a3dcafd3737d87d3bf42e9fd9efe7b2bc2 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: error_string.c 16746 2006-02-16 07:49:23Z lha $");
+RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $");
 
 #undef __attribute__
 #define __attribute__(X)
@@ -86,14 +86,26 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
     return 0;
 }
 
+/**
+ * Return the error message in context. On error or no error string,
+ * the function returns NULL.
+ *
+ * @param context Kerberos 5 context
+ *
+ * @return an error string, needs to be freed with
+ * krb5_free_error_string(). The functions return NULL on error.
+ *
+ * @ingroup krb5_error
+ */
+
 char * KRB5_LIB_FUNCTION
 krb5_get_error_string(krb5_context context)
 {
-    char *ret;
+    char *ret = NULL;
 
     HEIMDAL_MUTEX_lock(context->mutex);
-    ret = context->error_string;
-    context->error_string = NULL;
+    if (context->error_string)
+       ret = strdup(context->error_string);
     HEIMDAL_MUTEX_unlock(context->mutex);
     return ret;
 }
@@ -108,6 +120,19 @@ krb5_have_error_string(krb5_context context)
     return str != NULL;
 }
 
+/**
+ * Return the error message for `code' in context. On error the
+ * function returns NULL.
+ *
+ * @param context Kerberos 5 context
+ * @param code Error code related to the error
+ *
+ * @return an error string, needs to be freed with
+ * krb5_free_error_string(). The functions return NULL on error.
+ *
+ * @ingroup krb5_error
+ */
+
 char * KRB5_LIB_FUNCTION
 krb5_get_error_message(krb5_context context, krb5_error_code code)
 {
index b2b410269ede5f94aedbba80c34be7b81222b2d3..28e39afb42f74d094fd8bcb16cb838f16d423164 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: expand_hostname.c 18906 2006-11-04 03:34:57Z lha $");
+RCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $");
 
 static krb5_error_code
 copy_hostname(krb5_context context,
@@ -62,7 +62,7 @@ krb5_expand_hostname (krb5_context context,
     struct addrinfo *ai, *a, hints;
     int error;
 
-    if (!context->dns_canonicalize_hostname)
+    if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
        return copy_hostname (context, orig_hostname, new_hostname);
 
     memset (&hints, 0, sizeof(hints));
@@ -127,7 +127,7 @@ krb5_expand_hostname_realms (krb5_context context,
     int error;
     krb5_error_code ret = 0;
 
-    if (!context->dns_canonicalize_hostname)
+    if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
        return vanilla_hostname (context, orig_hostname, new_hostname,
                                 realms);
 
index 864efa8d7d1bc803af9862b00738af8a1d82eece..484df059abd6cd032710d13430ae653c11b55076 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: fcache.c 19379 2006-12-15 21:35:52Z lha $");
+RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $");
 
 typedef struct krb5_fcache{
     char *filename;
@@ -108,7 +108,7 @@ int
 _krb5_xunlock(krb5_context context, int fd)
 {
     int ret;
-#ifdef HAVE_FCNTL_LOCK
+#ifdef HAVE_FCNTL
     struct flock l;
     l.l_start = 0;
     l.l_len = 0;
@@ -463,9 +463,13 @@ init_fcc (krb5_context context,
     krb5_storage_set_eof_code(sp, KRB5_CC_END);
     ret = krb5_ret_int8(sp, &pvno);
     if(ret != 0) {
-       if(ret == KRB5_CC_END)
-           ret = ENOENT; /* empty file */
-       krb5_clear_error_string(context);
+       if(ret == KRB5_CC_END) {
+           krb5_set_error_string(context, "Empty credential cache file: %s",
+                                 FILENAME(id));
+           ret = ENOENT;
+       } else
+           krb5_set_error_string(context, "Error reading pvno in "
+                                 "cache file: %s", FILENAME(id));
        goto out;
     }
     if(pvno != 5) {
@@ -476,7 +480,8 @@ init_fcc (krb5_context context,
     }
     ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */
     if(ret != 0) {
-       krb5_clear_error_string(context);
+       krb5_set_error_string(context, "Error reading tag in "
+                             "cache file: %s", FILENAME(id));
        ret = KRB5_CC_FORMAT;
        goto out;
     }
@@ -489,7 +494,8 @@ init_fcc (krb5_context context,
        ret = krb5_ret_int16 (sp, &length);
        if(ret) {
            ret = KRB5_CC_FORMAT;
-           krb5_clear_error_string(context);
+           krb5_set_error_string(context, "Error reading tag length in "
+                             "cache file: %s", FILENAME(id));
            goto out;
        }
        while(length > 0) {
@@ -499,13 +505,15 @@ init_fcc (krb5_context context,
 
            ret = krb5_ret_int16 (sp, &dtag);
            if(ret) {
-               krb5_clear_error_string(context);
+               krb5_set_error_string(context, "Error reading dtag in "
+                                     "cache file: %s", FILENAME(id));
                ret = KRB5_CC_FORMAT;
                goto out;
            }
            ret = krb5_ret_int16 (sp, &data_len);
            if(ret) {
-               krb5_clear_error_string(context);
+               krb5_set_error_string(context, "Error reading dlength in "
+                                     "cache file: %s", FILENAME(id));
                ret = KRB5_CC_FORMAT;
                goto out;
            }
@@ -513,13 +521,15 @@ init_fcc (krb5_context context,
            case FCC_TAG_DELTATIME :
                ret = krb5_ret_int32 (sp, &context->kdc_sec_offset);
                if(ret) {
-                   krb5_clear_error_string(context);
+                   krb5_set_error_string(context, "Error reading kdc_sec in "
+                                         "cache file: %s", FILENAME(id));
                    ret = KRB5_CC_FORMAT;
                    goto out;
                }
                ret = krb5_ret_int32 (sp, &context->kdc_usec_offset);
                if(ret) {
-                   krb5_clear_error_string(context);
+                   krb5_set_error_string(context, "Error reading kdc_usec in "
+                                         "cache file: %s", FILENAME(id));
                    ret = KRB5_CC_FORMAT;
                    goto out;
                }
@@ -528,7 +538,9 @@ init_fcc (krb5_context context,
                for (i = 0; i < data_len; ++i) {
                    ret = krb5_ret_int8 (sp, &dummy);
                    if(ret) {
-                       krb5_clear_error_string(context);
+                       krb5_set_error_string(context, "Error reading unknown "
+                                             "tag in cache file: %s", 
+                                             FILENAME(id));
                        ret = KRB5_CC_FORMAT;
                        goto out;
                    }
@@ -755,6 +767,95 @@ fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
     return 0;
 }
 
+static krb5_error_code
+fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+    krb5_error_code ret = 0;
+
+    ret = rename(FILENAME(from), FILENAME(to));
+    if (ret && errno != EXDEV) {
+       ret = errno;
+       krb5_set_error_string(context,
+                             "Rename of file from %s to %s failed: %s", 
+                             FILENAME(from), FILENAME(to),
+                             strerror(ret));
+       return ret;
+    } else if (ret && errno == EXDEV) {
+       /* make a copy and delete the orignal */
+       krb5_ssize_t sz1, sz2;
+       int fd1, fd2;
+       char buf[BUFSIZ];
+
+       ret = fcc_open(context, from, &fd1, O_RDONLY | O_BINARY, 0);
+       if(ret)
+           return ret;
+
+       unlink(FILENAME(to));
+
+       ret = fcc_open(context, to, &fd2, 
+                      O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600);
+       if(ret)
+           goto out1;
+
+       while((sz1 = read(fd1, buf, sizeof(buf))) > 0) {
+           sz2 = write(fd2, buf, sz1);
+           if (sz1 != sz2) {
+               ret = EIO;
+               krb5_set_error_string(context,
+                                     "Failed to write data from one file "
+                                     "credential cache to the other");
+               goto out2;
+           }
+       }
+       if (sz1 < 0) {
+           ret = EIO;
+           krb5_set_error_string(context,
+                                 "Failed to read data from one file "
+                                 "credential cache to the other");
+           goto out2;
+       }
+       erase_file(FILENAME(from));
+           
+    out2:
+       fcc_unlock(context, fd2);
+       close(fd2);
+
+    out1:
+       fcc_unlock(context, fd1);
+       close(fd1);
+
+       if (ret) {
+           erase_file(FILENAME(to));
+           return ret;
+       }
+    }
+
+    /* make sure ->version is uptodate */
+    {
+       krb5_storage *sp;
+       int fd;
+       ret = init_fcc (context, to, &sp, &fd);
+       krb5_storage_free(sp);
+       fcc_unlock(context, fd);
+       close(fd);
+    }    
+    return ret;
+}
+
+static krb5_error_code
+fcc_default_name(krb5_context context, char **str)
+{
+    return _krb5_expand_default_cc_name(context, 
+                                       KRB5_DEFAULT_CCNAME_FILE,
+                                       str);
+}
+
+/**
+ * Variable containing the FILE based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
 const krb5_cc_ops krb5_fcc_ops = {
     "FILE",
     fcc_get_name,
@@ -774,5 +875,7 @@ const krb5_cc_ops krb5_fcc_ops = {
     fcc_get_version,
     fcc_get_cache_first,
     fcc_get_cache_next,
-    fcc_end_cache_get
+    fcc_end_cache_get,
+    fcc_move,
+    fcc_default_name
 };
index 7c3f128ae592a7560de6577a390d78bf6d36d559..fc78945c63a3bb977144472088e26b66472c1a3c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_cred.c 21669 2007-07-22 11:29:13Z lha $");
+RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $");
 
 /*
  * Take the `body' and encode it into `padata' using the credentials
@@ -761,14 +761,6 @@ get_cred_from_kdc_flags(krb5_context context,
 
     try_realm = krb5_config_get_string(context, NULL, "capaths", 
                                       client_realm, server_realm, NULL);
-    
-#if 1
-    /* XXX remove in future release */
-    if(try_realm == NULL)
-       try_realm = krb5_config_get_string(context, NULL, "libdefaults", 
-                                          "capath", server_realm, NULL);
-#endif
-
     if (try_realm == NULL)
        try_realm = client_realm;
 
index 1bb98737d1a8a454f02e9850a307dec66d59d8be..cb8b7c8641a6f1e3805bc5af29513a61da240f58 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_for_creds.c 17036 2006-04-10 09:28:15Z lha $");
+RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $");
 
 static krb5_error_code
 add_addrs(krb5_context context,
@@ -83,11 +83,23 @@ fail:
     return ret;
 }
 
-/*
- * Forward credentials for `client' to host `hostname`,
- * making them forwardable if `forwardable', and returning the
- * blob of data to sent in `out_data'.
- * If hostname == NULL, pick it from `server'
+/**
+ * Forward credentials for client to host hostname , making them
+ * forwardable if forwardable, and returning the blob of data to sent
+ * in out_data.  If hostname == NULL, pick it from server.
+ *
+ * @param context A kerberos 5 context.
+ * @param auth_context the auth context with the key to encrypt the out_data.
+ * @param hostname the host to forward the tickets too.
+ * @param client the client to delegate from.
+ * @param server the server to delegate the credential too.
+ * @param ccache credential cache to use.
+ * @param forwardable make the forwarded ticket forwabledable.
+ * @param out_data the resulting credential.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_credential
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -147,8 +159,31 @@ krb5_fwd_tgt_creds (krb5_context   context,
     return ret;
 }
 
-/*
+/**
+ * Gets tickets forwarded to hostname. If the tickets that are
+ * forwarded are address-less, the forwarded tickets will also be
+ * address-less.
+ * 
+ * If the ticket have any address, hostname will be used for figure
+ * out the address to forward the ticket too. This since this might
+ * use DNS, its insecure and also doesn't represent configured all
+ * addresses of the host. For example, the host might have two
+ * adresses, one IPv4 and one IPv6 address where the later is not
+ * published in DNS. This IPv6 address might be used communications
+ * and thus the resulting ticket useless.
  *
+ * @param context A kerberos 5 context.
+ * @param auth_context the auth context with the key to encrypt the out_data.
+ * @param ccache credential cache to use
+ * @param flags the flags to control the resulting ticket flags
+ * @param hostname the host to forward the tickets too.
+ * @param in_creds the in client and server ticket names.  The client
+ * and server components forwarded to the remote host.
+ * @param out_data the resulting credential.
+ *
+ * @return Return an error code or 0.
+ *
+ * @ingroup krb5_credential
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -174,39 +209,31 @@ krb5_get_forwarded_creds (krb5_context        context,
     struct addrinfo *ai;
     int save_errno;
     krb5_creds *ticket;
-    char *realm;
-
-    realm = in_creds->client->realm;
 
+    paddrs = NULL;
     addrs.len = 0;
     addrs.val = NULL;
-    paddrs = &addrs;
 
-    {
+    ret = krb5_get_credentials(context, 0, ccache, in_creds, &ticket);
+    if(ret == 0) {
+       if (ticket->addresses.len)
+           paddrs = &addrs;
+       krb5_free_creds (context, ticket);
+    } else {
        krb5_boolean noaddr;
-       krb5_appdefault_boolean(context, NULL, realm,
+       krb5_appdefault_boolean(context, NULL,
+                               krb5_principal_get_realm(context, 
+                                                        in_creds->client),
                                "no-addresses", KRB5_ADDRESSLESS_DEFAULT,
                                &noaddr);
-       if (noaddr)
-           paddrs = NULL;
+       if (!noaddr)
+           paddrs = &addrs;
     }
        
     /*
-     * If tickets are address-less, forward address-less tickets.
+     * If tickets have addresses, get the address of the remote host.
      */
 
-    if (paddrs) {
-       ret = _krb5_get_krbtgt (context,
-                               ccache,
-                               realm,
-                               &ticket);
-       if(ret == 0) {
-           if (ticket->addresses.len == 0)
-               paddrs = NULL;
-           krb5_free_creds (context, ticket);
-       }
-    }
-    
     if (paddrs != NULL) {
 
        ret = getaddrinfo (hostname, NULL, NULL, &ai);
@@ -233,9 +260,8 @@ krb5_get_forwarded_creds (krb5_context          context,
                             in_creds,
                             &out_creds);
     krb5_free_addresses (context, &addrs);
-    if (ret) {
+    if (ret)
        return ret;
-    }
 
     memset (&cred, 0, sizeof(cred));
     cred.pvno = 5;
@@ -373,6 +399,14 @@ krb5_get_forwarded_creds (krb5_context         context,
     if(buf_size != len)
        krb5_abortx(context, "internal error in ASN.1 encoder");
 
+    /**
+     * Some older of the MIT gssapi library used clear-text tickets
+     * (warped inside AP-REQ encryption), use the krb5_auth_context
+     * flag KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED to support those
+     * tickets. The session key is used otherwise to encrypt the
+     * forwarded ticket.
+     */
+
     if (auth_context->flags & KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED) {
        cred.enc_part.etype = ENCTYPE_NULL;
        cred.enc_part.kvno = NULL;
index ec106bb7eccfc58a9ccd8dfd2883338e6ec36853..a9ed3857d036448ebef074b5a73fb43502e016a4 100644 (file)
@@ -145,7 +145,7 @@ _krb5_extract_ticket(krb5_context context,
 flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
 flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ;
 
-    ret = _krb5_principalname2krb5_principal (context,
+   ret = _krb5_principalname2krb5_principal (context,
                                              &tmp_principal,
                                              rep->kdc_rep.cname,
                                              rep->kdc_rep.crealm);
index bd250cef2bdfd885753ae9c1e3674359d179a478..a59c903bd9e1f49a4ff4ecb967784c2dbe99057f 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds.c 21712 2007-07-27 14:23:41Z lha $");
+RCSID("$Id: init_creds.c 21711 2007-07-27 14:22:02Z lha $");
 
 void KRB5_LIB_FUNCTION
 krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt)
index 0043b5ef3c1d45744eb82cdd9b18d02156da7a31..441adff8fdf9e75f9fcb63ec926db345db12b8e6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: init_creds_pw.c 21428 2007-07-10 12:31:58Z lha $");
+RCSID("$Id: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $");
 
 typedef struct krb5_get_init_creds_ctx {
     KDCOptions flags;
@@ -1547,9 +1547,15 @@ krb5_get_init_creds_password(krb5_context context,
     char buf[BUFSIZ];
     krb5_error_code ret;
 
-    if (in_options == NULL)
+    if (in_options == NULL) {
+       const char *realm = krb5_principal_get_realm(context, client);
        ret = krb5_get_init_creds_opt_alloc(context, &options);
-    else
+       if (ret == 0)
+           krb5_get_init_creds_opt_set_default_flags(context, 
+                                                     NULL, 
+                                                     realm, 
+                                                     options);
+    } else
        ret = _krb5_get_init_creds_opt_copy(context, in_options, &options);
     if (ret)
        return ret;
index c945a9ce135260ed1732099b0039b5cc3b2bb83c..8afaa6ea80a171cf1296e74e6a27ed4e355c4a07 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "kcm.h"
 
-RCSID("$Id: kcm.c 17442 2006-05-05 09:31:15Z lha $");
+RCSID("$Id: kcm.c 22108 2007-12-03 17:23:53Z lha $");
 
 typedef struct krb5_kcmcache {
     char *name;
@@ -829,6 +829,27 @@ kcm_get_version(krb5_context context,
     return 0;
 }
 
+static krb5_error_code
+kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+    krb5_set_error_string(context, "kcm_move not implemented");
+    return EINVAL;
+}
+
+static krb5_error_code
+kcm_default_name(krb5_context context, char **str)
+{
+    return _krb5_expand_default_cc_name(context, 
+                                       KRB5_DEFAULT_CCNAME_KCM,
+                                       str);
+}
+
+/**
+ * Variable containing the KCM based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
 const krb5_cc_ops krb5_kcm_ops = {
     "KCM",
     kcm_get_name,
@@ -845,7 +866,12 @@ const krb5_cc_ops krb5_kcm_ops = {
     kcm_end_get,
     kcm_remove_cred,
     kcm_set_flags,
-    kcm_get_version
+    kcm_get_version,
+    NULL,
+    NULL,
+    NULL,
+    kcm_move,
+    kcm_default_name
 };
 
 krb5_boolean
index f6c7858c12ec1e77ee66dc3fbc4c987d902728fc..79a3f20e79d794bb6f3fa553a86937a2bddcc57c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab.c 20211 2007-02-09 07:11:03Z lha $");
+RCSID("$Id: keytab.c 22532 2008-01-27 11:59:18Z lha $");
 
 /*
  * Register a new keytab in `ops'
@@ -337,8 +337,9 @@ krb5_kt_get_entry(krb5_context context,
 
     ret = krb5_kt_start_seq_get (context, id, &cursor);
     if (ret) {
-       krb5_clear_error_string(context);
-       return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */
+       /* This is needed for krb5_verify_init_creds, but keep error
+        * string from previous error for the human. */
+       return KRB5_KT_NOTFOUND;
     }
 
     entry->vno = 0;
index 4ada3a463ea8ef071b6435f79f96c365bfce4a69..be195d96c26d67104c80d71bb2cf3078ab2a203d 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_file.c 17457 2006-05-05 12:36:57Z lha $");
+RCSID("$Id: keytab_file.c 22532 2008-01-27 11:59:18Z lha $");
 
 #define KRB5_KT_VNO_1 1
 #define KRB5_KT_VNO_2 2
@@ -334,8 +334,8 @@ fkt_start_seq_get_int(krb5_context context,
     c->fd = open (d->filename, flags);
     if (c->fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, "%s: %s", d->filename,
-                             strerror(ret));
+       krb5_set_error_string(context, "keytab %s open failed: %s", 
+                             d->filename, strerror(ret));
        return ret;
     }
     ret = _krb5_xlock(context, c->fd, exclusive, d->filename);
index 77455ba5f7c260a5bccfbf3a9cdf7b3377b6a5d4..aa612add09780557ecf1368950517bd0335a0126 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_keyfile.c 20695 2007-05-30 14:09:09Z lha $");
+RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $");
 
 /* afs keyfile operations --------------------------------------- */
 
@@ -197,8 +197,8 @@ akf_start_seq_get(krb5_context context,
     c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600);
     if (c->fd < 0) {
        ret = errno;
-       krb5_set_error_string(context, "open(%s): %s", d->filename,
-                             strerror(ret));
+       krb5_set_error_string(context, "keytab afs keyfil open %s failed: %s",
+                             d->filename, strerror(ret));
        return ret;
     }
 
index 907836c144f768c07bac2cf2f01117472b7336e3..32bb00141ab960a754e3d2f781bb112808f9820c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_krb4.c 17046 2006-04-10 17:10:53Z lha $");
+RCSID("$Id: keytab_krb4.c 22532 2008-01-27 11:59:18Z lha $");
 
 struct krb4_kt_data {
     char *filename;
@@ -134,14 +134,15 @@ krb4_kt_start_seq_get_int (krb5_context context,
     if (c->fd < 0) {
        ret = errno;
        free (ed);
-       krb5_set_error_string(context, "open(%s): %s", d->filename,
-                             strerror(ret));
+       krb5_set_error_string(context, "keytab krb5 open %s failed: %s", 
+                             d->filename, strerror(ret));
        return ret;
     }
     c->sp = krb5_storage_from_fd(c->fd);
     if(c->sp == NULL) {
        close(c->fd);
        free(ed);
+       krb5_set_error_string(context, "malloc: out of memory");
        return ENOMEM;
     }
     krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
@@ -369,8 +370,11 @@ krb4_kt_remove_entry(krb5_context context,
        if(fd < 0) {
            memset(data.data, 0, data.length);
            krb5_data_free(&data);
-           if(errno == EACCES || errno == EROFS) 
+           if(errno == EACCES || errno == EROFS) {
+               krb5_set_error_string(context, "failed to open %s for writing",
+                                     d->filename);
                return KRB5_KT_NOWRITE;
+           }
            return errno;
        }
 
@@ -378,14 +382,16 @@ krb4_kt_remove_entry(krb5_context context,
            memset(data.data, 0, data.length);
            krb5_data_free(&data);
            close(fd);
-           krb5_set_error_string(context, "failed writing to \"%s\"", d->filename);
+           krb5_set_error_string(context, "failed writing to file %s", 
+                                 d->filename);
            return errno;
        }
        memset(data.data, 0, data.length);
        if(fstat(fd, &st) < 0) {
            krb5_data_free(&data);
            close(fd);
-           krb5_set_error_string(context, "failed getting size of \"%s\"", d->filename);
+           krb5_set_error_string(context, "failed getting size of file %s", 
+                                 d->filename);
            return errno;
        }
        st.st_size -= data.length;
@@ -396,7 +402,8 @@ krb4_kt_remove_entry(krb5_context context,
            if(n <= 0) {
                krb5_data_free(&data);
                close(fd);
-               krb5_set_error_string(context, "failed writing to \"%s\"", d->filename);
+               krb5_set_error_string(context, "failed writing to file %s",
+                                     d->filename);
                return errno;
                
            }
@@ -405,17 +412,20 @@ krb4_kt_remove_entry(krb5_context context,
        if(ftruncate(fd, data.length) < 0) {
            krb5_data_free(&data);
            close(fd);
-           krb5_set_error_string(context, "failed truncating \"%s\"", d->filename);
+           krb5_set_error_string(context, "failed truncating file %s",
+                                 d->filename);
            return errno;
        }
        krb5_data_free(&data);
        if(close(fd) < 0) {
-           krb5_set_error_string(context, "error closing \"%s\"", d->filename);
+           krb5_set_error_string(context, "error closing %s",
+                                 d->filename);
            return errno;
        }
        return 0;
     } else {
        krb5_storage_free(sp);
+       krb5_set_error_string(context, "Keytab entry not found");
        return KRB5_KT_NOTFOUND;
     }
 }
index 9a84dde61a71ac0c3268b0aef3f7077c2da9db0c..7e04446fe07ccbfc529522acf8875e560e2fa963 100644 (file)
@@ -276,7 +276,7 @@ _krb5_mk_req_internal (
        krb5_key_usage /*checksum_usage*/,
        krb5_key_usage /*encrypt_usage*/);
 
-void KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
 _krb5_n_fold (
        const void */*str*/,
        size_t /*len*/,
@@ -292,7 +292,7 @@ _krb5_oid_to_enctype (
 krb5_error_code
 _krb5_pac_sign (
        krb5_context /*context*/,
-       struct krb5_pac */*p*/,
+       krb5_pac /*p*/,
        time_t /*authtime*/,
        krb5_principal /*principal*/,
        const krb5_keyblock */*server_key*/,
@@ -396,13 +396,6 @@ _krb5_plugin_get_next (struct krb5_plugin */*p*/);
 void *
 _krb5_plugin_get_symbol (struct krb5_plugin */*p*/);
 
-krb5_error_code
-_krb5_plugin_register (
-       krb5_context /*context*/,
-       enum krb5_plugin_type /*type*/,
-       const char */*name*/,
-       void */*symbol*/);
-
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_principal2principalname (
        PrincipalName */*p*/,
index 740b394be8acadad59e45349b851482240b927ee..647d8886b7ccf7317e1083512411499e8c5ff919 100644 (file)
@@ -670,6 +670,12 @@ krb5_cc_initialize (
        krb5_ccache /*id*/,
        krb5_principal /*primary_principal*/);
 
+krb5_error_code
+krb5_cc_move (
+       krb5_context /*context*/,
+       krb5_ccache /*from*/,
+       krb5_ccache /*to*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_cc_new_unique (
        krb5_context /*context*/,
@@ -1329,6 +1335,13 @@ krb5_digest_init_request (
        krb5_realm /*realm*/,
        krb5_ccache /*ccache*/);
 
+krb5_error_code
+krb5_digest_probe (
+       krb5_context /*context*/,
+       krb5_realm /*realm*/,
+       krb5_ccache /*ccache*/,
+       unsigned */*flags*/);
+
 krb5_boolean
 krb5_digest_rep_get_status (
        krb5_context /*context*/,
@@ -1606,6 +1619,9 @@ krb5_err (
        ...)
     __attribute__ ((noreturn, format (printf, 4, 5)));
 
+krb5_error_code KRB5_LIB_FUNCTION 
+    __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_error_from_rd_error (
        krb5_context /*context*/,
@@ -1694,11 +1710,6 @@ krb5_free_creds (
        krb5_context /*context*/,
        krb5_creds */*c*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-krb5_free_creds_contents (
-       krb5_context /*context*/,
-       krb5_creds */*c*/);
-
 void KRB5_LIB_FUNCTION
 krb5_free_data (
        krb5_context /*context*/,
@@ -2243,6 +2254,14 @@ krb5_get_pw_salt (
        krb5_const_principal /*principal*/,
        krb5_salt */*salt*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_get_renewed_creds (
+       krb5_context /*context*/,
+       krb5_creds */*creds*/,
+       krb5_const_principal /*client*/,
+       krb5_ccache /*ccache*/,
+       const char */*in_tkt_service*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_get_server_rcache (
        krb5_context /*context*/,
@@ -2797,45 +2816,45 @@ krb5_openlog (
 krb5_error_code
 krb5_pac_add_buffer (
        krb5_context /*context*/,
-       struct krb5_pac */*p*/,
+       krb5_pac /*p*/,
        uint32_t /*type*/,
        const krb5_data */*data*/);
 
 void
 krb5_pac_free (
        krb5_context /*context*/,
-       struct krb5_pac */*pac*/);
+       krb5_pac /*pac*/);
 
 krb5_error_code
 krb5_pac_get_buffer (
        krb5_context /*context*/,
-       struct krb5_pac */*p*/,
+       krb5_pac /*p*/,
        uint32_t /*type*/,
        krb5_data */*data*/);
 
 krb5_error_code
 krb5_pac_get_types (
        krb5_context /*context*/,
-       struct krb5_pac */*p*/,
+       krb5_pac /*p*/,
        size_t */*len*/,
        uint32_t **/*types*/);
 
 krb5_error_code
 krb5_pac_init (
        krb5_context /*context*/,
-       struct krb5_pac **/*pac*/);
+       krb5_pac */*pac*/);
 
 krb5_error_code
 krb5_pac_parse (
        krb5_context /*context*/,
        const void */*ptr*/,
        size_t /*len*/,
-       struct krb5_pac **/*pac*/);
+       krb5_pac */*pac*/);
 
 krb5_error_code
 krb5_pac_verify (
        krb5_context /*context*/,
-       const struct krb5_pac */*pac*/,
+       const krb5_pac /*pac*/,
        time_t /*authtime*/,
        krb5_const_principal /*principal*/,
        const krb5_keyblock */*server*/,
@@ -2887,6 +2906,13 @@ krb5_password_key_proc (
        krb5_const_pointer /*keyseed*/,
        krb5_keyblock **/*key*/);
 
+krb5_error_code
+krb5_plugin_register (
+       krb5_context /*context*/,
+       enum krb5_plugin_type /*type*/,
+       const char */*name*/,
+       void */*symbol*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_prepend_config_files (
        const char */*filelist*/,
index 4f9a63bf0549566ef20ef466051f3e869c9547d8..571eb6192ae09b9e33c1e7a540f5a1b4d5db1be6 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5.h 21551 2007-07-15 09:03:39Z lha $ */
+/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */
 
 #ifndef __KRB5_H__
 #define __KRB5_H__
@@ -75,15 +75,16 @@ typedef struct krb5_crypto_data *krb5_crypto;
 struct krb5_get_creds_opt_data;
 typedef struct krb5_get_creds_opt_data *krb5_get_creds_opt;
 
-struct krb5_digest;
-typedef struct krb5_digest *krb5_digest;
-struct krb5_ntlm;
-typedef struct krb5_ntlm *krb5_ntlm;
+struct krb5_digest_data;
+typedef struct krb5_digest_data *krb5_digest;
+struct krb5_ntlm_data;
+typedef struct krb5_ntlm_data *krb5_ntlm;
 
-typedef struct krb5_pac *krb5_pac;
+struct krb5_pac_data;
+typedef struct krb5_pac_data *krb5_pac;
 
-typedef struct krb5_rd_req_in_ctx *krb5_rd_req_in_ctx;
-typedef struct krb5_rd_req_out_ctx *krb5_rd_req_out_ctx;
+typedef struct krb5_rd_req_in_ctx_data *krb5_rd_req_in_ctx;
+typedef struct krb5_rd_req_out_ctx_data *krb5_rd_req_out_ctx;
 
 typedef CKSUMTYPE krb5_cksumtype;
 
@@ -417,6 +418,8 @@ typedef struct krb5_cc_ops {
     krb5_error_code (*get_cache_first)(krb5_context, krb5_cc_cursor *);
     krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *);
     krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor);
+    krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache);
+    krb5_error_code (*default_name)(krb5_context, char **);
 } krb5_cc_ops;
 
 struct krb5_log_facility;
@@ -753,7 +756,7 @@ enum {
     KRB5_PRINCIPAL_UNPARSE_DISPLAY = 4
 };
 
-typedef struct krb5_sendto_ctx *krb5_sendto_ctx;
+typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx;
 
 #define KRB5_SENDTO_DONE       0
 #define KRB5_SENDTO_RESTART    1
index b53d77ef18854fd696879b16558dd5c0742bb199..59a38425c252473c9552c8368f513ce1c20153ff 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5_ccapi.h 17442 2006-05-05 09:31:15Z lha $ */
+/* $Id: krb5_ccapi.h 22090 2007-12-02 23:23:43Z lha $ */
 
 #ifndef KRB5_CCAPI_H
 #define KRB5_CCAPI_H 1
@@ -180,18 +180,18 @@ typedef struct cc_ccache_functions {
     cc_int32 (*destroy)(cc_ccache_t);
     cc_int32 (*set_default)(cc_ccache_t);
     cc_int32 (*get_credentials_version)(cc_ccache_t, cc_uint32*);
-    cc_int32 (*get_name)(cc_ccache_t ccache,cc_string_t*);
+    cc_int32 (*get_name)(cc_ccache_tcc_string_t*);
     cc_int32 (*get_principal)(cc_ccache_t, cc_uint32, cc_string_t*);
     cc_int32 (*set_principal)(cc_ccache_t, cc_uint32, const char*);
     cc_int32 (*store_credentials)(cc_ccache_t, const cc_credentials_union*);
     cc_int32 (*remove_credentials)(cc_ccache_t, cc_credentials_t);
     cc_int32 (*new_credentials_iterator)(cc_ccache_t,
                                         cc_credentials_iterator_t*);
-    cc_int32 (*move)(cc_ccache_t source, cc_ccache_t);
+    cc_int32 (*move)(cc_ccache_t, cc_ccache_t);
     cc_int32 (*lock)(cc_ccache_t, cc_uint32, cc_uint32);
     cc_int32 (*unlock)(cc_ccache_t);
     cc_int32 (*get_last_default_time)(cc_ccache_t, cc_time_t*);
-    cc_int32 (*get_change_time)(cc_ccache_t ccache, cc_time_t*);
+    cc_int32 (*get_change_time)(cc_ccache_t, cc_time_t*);
     cc_int32 (*compare)(cc_ccache_t, cc_ccache_t, cc_uint32*);
     cc_int32 (*get_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t *);
     cc_int32 (*set_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t);
index b41e6e1182eea180d0a788ba333d0e83bcc324aa..8b7c41cc80d957af40104a7d43f7401e8dddae3e 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5_locl.h 21552 2007-07-15 09:04:00Z lha $ */
+/* $Id: krb5_locl.h 22226 2007-12-08 21:31:53Z lha $ */
 
 #ifndef __KRB5_LOCL_H__
 #define __KRB5_LOCL_H__
@@ -231,14 +231,18 @@ typedef struct krb5_context_data {
     krb5_addresses *ignore_addresses;
     char *default_cc_name;
     char *default_cc_name_env;
+    int default_cc_name_set;
     void *mutex;                       /* protects error_string/error_buf */
     int large_msg_size;
-    int dns_canonicalize_hostname;
+    int flags;
+#define KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME   1
+#define KRB5_CTX_F_CHECK_PAC                   2
     struct send_to_kdc *send_to_kdc;
 } krb5_context_data;
 
 #define KRB5_DEFAULT_CCNAME_FILE "FILE:/tmp/krb5cc_%{uid}"
 #define KRB5_DEFAULT_CCNAME_API "API:"
+#define KRB5_DEFAULT_CCNAME_KCM "KCM:%{uid}"
 
 #define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH            1
 #define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH           2
@@ -248,11 +252,11 @@ typedef struct krb5_context_data {
  * Configurable options
  */
 
-#ifndef KRB5_DEFAULT_CCNAME
+#ifndef KRB5_DEFAULT_CCTYPE
 #ifdef __APPLE__
-#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_API
+#define KRB5_DEFAULT_CCTYPE (&krb5_acc_ops)
 #else
-#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_FILE
+#define KRB5_DEFAULT_CCTYPE (&krb5_fcc_ops)
 #endif
 #endif
 
index ff9261a7db75dbbe62f2b5bc7e28aa20d280e9d5..01bcb09d3bea173a95b422d7bd46996fef54274c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: mcache.c 19834 2007-01-11 09:26:21Z lha $");
+RCSID("$Id: mcache.c 22107 2007-12-03 17:22:51Z lha $");
 
 typedef struct krb5_mcache {
     char *name;
@@ -401,6 +401,57 @@ mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
     return 0;
 }
 
+static krb5_error_code
+mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
+{
+    krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to);
+    struct link *creds;
+    krb5_principal principal;
+    krb5_mcache **n;
+
+    HEIMDAL_MUTEX_lock(&mcc_mutex);
+
+    /* drop the from cache from the linked list to avoid lookups */
+    for(n = &mcc_head; n && *n; n = &(*n)->next) {
+       if(mfrom == *n) {
+           *n = mfrom->next;
+           break;
+       }
+    }
+
+    /* swap creds */
+    creds = mto->creds;
+    mto->creds = mfrom->creds;
+    mfrom->creds = creds;
+    /* swap principal */
+    principal = mto->primary_principal;
+    mto->primary_principal = mfrom->primary_principal;
+    mfrom->primary_principal = principal;
+
+    HEIMDAL_MUTEX_unlock(&mcc_mutex);
+    mcc_destroy(context, from);
+
+    return 0;
+}
+
+static krb5_error_code
+mcc_default_name(krb5_context context, char **str)
+{
+    *str = strdup("MEMORY:");
+    if (*str == NULL) {
+       krb5_set_error_string(context, "out of memory");
+       return ENOMEM;
+    }
+    return 0;
+}
+
+
+/**
+ * Variable containing the MEMORY based credential cache implemention.
+ *
+ * @ingroup krb5_ccache
+ */
+
 const krb5_cc_ops krb5_mcc_ops = {
     "MEMORY",
     mcc_get_name,
@@ -420,5 +471,7 @@ const krb5_cc_ops krb5_mcc_ops = {
     NULL,
     mcc_get_cache_first,
     mcc_get_cache_next,
-    mcc_end_cache_get
+    mcc_end_cache_get,
+    mcc_move,
+    mcc_default_name
 };
index 1474a76b7752e3a3c3f774bb2d4a4763f9d1f6e6..53528cfd1f781b44022fe3e43ccde37348930bb1 100644 (file)
 
 #include "krb5_locl.h"
 
-RCSID("$Id: n-fold.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $");
 
-static void
+static krb5_error_code
 rr13(unsigned char *buf, size_t len)
 {
     unsigned char *tmp;
     int bytes = (len + 7) / 8;
     int i;
     if(len == 0)
-       return;
+       return 0;
     {
        const int bits = 13 % len;
        const int lbit = len % 8;
     
        tmp = malloc(bytes);
+       if (tmp == NULL)
+           return ENOMEM;
        memcpy(tmp, buf, bytes);
        if(lbit) {
            /* pad final byte with inital bits */
@@ -75,9 +77,10 @@ rr13(unsigned char *buf, size_t len)
        }
        free(tmp);
     }
+    return 0;
 }
 
-/* Add `b' to `a', both beeing one's complement numbers. */
+/* Add `b' to `a', both being one's complement numbers. */
 static void
 add1(unsigned char *a, unsigned char *b, size_t len)
 {
@@ -95,22 +98,28 @@ add1(unsigned char *a, unsigned char *b, size_t len)
     }
 }
 
-void KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
 _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
 {
     /* if len < size we need at most N * len bytes, ie < 2 * size;
        if len > size we need at most 2 * len */
+    krb5_error_code ret = 0;
     size_t maxlen = 2 * max(size, len);
     size_t l = 0;
     unsigned char *tmp = malloc(maxlen);
     unsigned char *buf = malloc(len);
     
+    if (tmp == NULL || buf == NULL) 
+       return ENOMEM;
+
     memcpy(buf, str, len);
     memset(key, 0, size);
     do {
        memcpy(tmp + l, buf, len);
        l += len;
-       rr13(buf, len * 8);
+       ret = rr13(buf, len * 8);
+       if (ret)
+           goto out;
        while(l >= size) {
            add1(key, tmp, size);
            l -= size;
@@ -119,8 +128,10 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size)
            memmove(tmp, tmp + size, l);
        }
     } while(l != 0);
+out:
     memset(buf, 0, len);
     free(buf);
     memset(tmp, 0, maxlen);
     free(tmp);
+    return ret;
 }
index f7a5e83ea3470b504bbd042c879f9f180e6d7196..0b44ca1da381fe9605983e0be37d645d786eda25 100644 (file)
@@ -32,8 +32,9 @@
  */
 
 #include "krb5_locl.h"
+#include <wind.h>
 
-RCSID("$Id: pac.c 21149 2007-06-18 21:50:22Z lha $");
+RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $");
 
 struct PAC_INFO_BUFFER {
     uint32_t type;
@@ -48,7 +49,7 @@ struct PACTYPE {
     struct PAC_INFO_BUFFER buffers[1];
 };
 
-struct krb5_pac {
+struct krb5_pac_data {
     struct PACTYPE *pac;
     krb5_data data;
     struct PAC_INFO_BUFFER *server_checksum;
@@ -82,10 +83,10 @@ static const char zeros[PAC_ALIGNMENT] = { 0 };
 
 krb5_error_code
 krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
-              struct krb5_pac **pac)
+              krb5_pac *pac)
 {
     krb5_error_code ret;
-    struct krb5_pac *p;
+    krb5_pac p;
     krb5_storage *sp = NULL;
     uint32_t i, tmp, tmp2, header_end;
 
@@ -216,10 +217,10 @@ out:
 }
 
 krb5_error_code
-krb5_pac_init(krb5_context context, struct krb5_pac **pac)
+krb5_pac_init(krb5_context context, krb5_pac *pac)
 {
     krb5_error_code ret;
-    struct krb5_pac *p;
+    krb5_pac p;
 
     p = calloc(1, sizeof(*p));
     if (p == NULL) {
@@ -248,7 +249,7 @@ krb5_pac_init(krb5_context context, struct krb5_pac **pac)
 }
 
 krb5_error_code
-krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p,
+krb5_pac_add_buffer(krb5_context context, krb5_pac p,
                    uint32_t type, const krb5_data *data)
 {
     krb5_error_code ret;
@@ -316,7 +317,7 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p,
 }
 
 krb5_error_code
-krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p,
+krb5_pac_get_buffer(krb5_context context, krb5_pac p,
                    uint32_t type, krb5_data *data)
 {
     krb5_error_code ret;
@@ -361,7 +362,7 @@ krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p,
 
 krb5_error_code
 krb5_pac_get_types(krb5_context context,
-                  struct krb5_pac *p,
+                  krb5_pac p,
                   size_t *len,
                   uint32_t **types)
 {
@@ -385,7 +386,7 @@ krb5_pac_get_types(krb5_context context,
  */
 
 void
-krb5_pac_free(krb5_context context, struct krb5_pac *pac)
+krb5_pac_free(krb5_context context, krb5_pac pac)
 {
     krb5_data_free(&pac->data);
     free(pac->pac);
@@ -564,51 +565,48 @@ verify_logonname(krb5_context context,
     ret = krb5_storage_read(sp, s, len);
     if (ret != len) {
        krb5_storage_free(sp);
-       krb5_set_error_string(context, "Failed to read pac logon name");
+       krb5_set_error_string(context, "Failed to read PAC logon name");
        return EINVAL;
     }
     krb5_storage_free(sp);
-#if 1 /* cheat for now */
-    {
-       size_t i;
-
-       if (len & 1) {
-           krb5_set_error_string(context, "PAC logon name malformed");
-           return EINVAL;
-       }
-
-       for (i = 0; i < len / 2; i++) {
-           if (s[(i * 2) + 1]) {
-               krb5_set_error_string(context, "PAC logon name not ASCII");
-               return EINVAL;
-           }
-           s[i] = s[i * 2];
-       }
-       s[i] = '\0';
-    }
-#else
     {
+       size_t ucs2len = len / 2;
        uint16_t *ucs2;
-       ssize_t ucs2len;
        size_t u8len;
+       unsigned int flags = WIND_RW_LE;
 
-       ucs2 = malloc(sizeof(ucs2[0]) * len / 2);
-       if (ucs2)
-           abort();
-       ucs2len = wind_ucs2read(s, len / 2, ucs2);
+       ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
+       if (ucs2 == NULL) {
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+       ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len);
        free(s);
-       if (len < 0)
-           return -1;
-       ret = wind_ucs2toutf8(ucs2, ucs2len, NULL, &u8len);
-       if (ret < 0)
-           abort();
-       s = malloc(u8len + 1);
-       if (s == NULL)
-           abort();
-       wind_ucs2toutf8(ucs2, ucs2len, s, &u8len);
+       if (ret) {
+           free(ucs2);
+           krb5_set_error_string(context, "Failed to convert string to UCS-2");
+           return ret;
+       }
+       ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
+       if (ret) {
+           free(ucs2);
+           krb5_set_error_string(context, "Failed to count length of UCS-2 string");
+           return ret;
+       }
+       u8len += 1; /* Add space for NUL */
+       s = malloc(u8len);
+       if (s == NULL) {
+           free(ucs2);
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+       ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len);
        free(ucs2);
+       if (ret) {
+           krb5_set_error_string(context, "Failed to convert to UTF-8");
+           return ret;
+       }
     }
-#endif
     ret = krb5_parse_name_flags(context, s, KRB5_PRINCIPAL_PARSE_NO_REALM, &p2);
     free(s);
     if (ret)
@@ -703,7 +701,7 @@ out:
 
 krb5_error_code
 krb5_pac_verify(krb5_context context, 
-               const struct krb5_pac *pac,
+               const krb5_pac pac,
                time_t authtime,
                krb5_const_principal principal,
                const krb5_keyblock *server,
@@ -840,7 +838,7 @@ pac_checksum(krb5_context context,
 
 krb5_error_code
 _krb5_pac_sign(krb5_context context,
-              struct krb5_pac *p,
+              krb5_pac p,
               time_t authtime,
               krb5_principal principal,
               const krb5_keyblock *server_key,
index c8587770f4ca3096c114ccd58f1a91ab71b228ce..4a585bff070dade2c57b63285d90b9d705809dc2 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: pkinit.c 21684 2007-07-23 23:09:10Z lha $");
+RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $");
 
 struct krb5_dh_moduli {
     char *name;
@@ -139,17 +139,59 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f)
     return bn;
 }
 
+struct certfind {
+    const char *type;
+    const heim_oid *oid;
+};
+
+/*
+ * Try searchin the key by to use by first looking for for PK-INIT
+ * EKU, then the Microsoft smart card EKU and last, no special EKU at all.
+ */
 
 static krb5_error_code
-_krb5_pk_create_sign(krb5_context context,
-                    const heim_oid *eContentType,
-                    krb5_data *eContent,
-                    struct krb5_pk_identity *id,
-                    hx509_peer_info peer,
-                    krb5_data *sd_data)
+find_cert(krb5_context context, struct krb5_pk_identity *id, 
+         hx509_query *q, hx509_cert *cert)
 {
-    hx509_cert cert;
-    hx509_query *q;
+    struct certfind cf[3] = { 
+       { "PKINIT EKU" },
+       { "MS EKU" },
+       { "no" }
+    };
+    int i, ret;
+
+    cf[0].oid = oid_id_pkekuoid();
+    cf[1].oid = oid_id_pkinit_ms_eku();
+    cf[2].oid = NULL;
+
+    for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) {
+       ret = hx509_query_match_eku(q, cf[i].oid);
+       if (ret) {
+           _krb5_pk_copy_error(context, id->hx509ctx, ret, 
+                               "Failed setting %s OID", cf[i].type);
+           return ret;
+       }
+
+       ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert);
+       if (ret == 0)
+           break;
+       _krb5_pk_copy_error(context, id->hx509ctx, ret, 
+                           "Failed cert for finding %s OID", cf[i].type);
+    }
+    return ret;
+}
+
+
+static krb5_error_code
+create_signature(krb5_context context,
+                const heim_oid *eContentType,
+                krb5_data *eContent,
+                struct krb5_pk_identity *id,
+                hx509_peer_info peer,
+                krb5_data *sd_data)
+{
+    hx509_cert cert = NULL;
+    hx509_query *q = NULL;
     int ret;
 
     ret = hx509_query_alloc(id->hx509ctx, &q);
@@ -162,13 +204,10 @@ _krb5_pk_create_sign(krb5_context context,
     hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
     hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
 
-    ret = hx509_certs_find(id->hx509ctx, id->certs, q, &cert);
+    ret = find_cert(context, id, q, &cert);
     hx509_query_free(id->hx509ctx, q);
-    if (ret) {
-       _krb5_pk_copy_error(context, id->hx509ctx, ret, 
-                           "Find certificate to signed CMS data");
+    if (ret)
        return ret;
-    }
 
     ret = hx509_cms_create_signed_1(id->hx509ctx,
                                    0,
@@ -181,11 +220,14 @@ _krb5_pk_create_sign(krb5_context context,
                                    NULL,
                                    id->certs,
                                    sd_data);
-    if (ret)
-       _krb5_pk_copy_error(context, id->hx509ctx, ret, "create CMS signedData");
     hx509_cert_free(cert);
+    if (ret) {
+       _krb5_pk_copy_error(context, id->hx509ctx, ret,
+                           "Create CMS signedData");
+       return ret;
+    }
 
-    return ret;
+    return 0;
 }
 
 static int
@@ -212,8 +254,7 @@ cert2epi(hx509_context context, void *ctx, hx509_cert c)
            return ENOMEM;
        }
     
-       ret = hx509_name_to_der_name(subject, &id.subjectName->data,
-                                    &id.subjectName->length);
+       ret = hx509_name_binary(subject, id.subjectName);
        if (ret) {
            hx509_name_free(&subject);
            free_ExternalPrincipalIdentifier(&id);
@@ -544,12 +585,8 @@ pk_mk_padata(krb5_context context,
     } else
        krb5_abortx(context, "internal pkinit error");
 
-    ret = _krb5_pk_create_sign(context,
-                              oid,
-                              &buf,
-                              ctx->id,
-                              ctx->peer,
-                              &sd_buf);
+    ret = create_signature(context, oid, &buf, ctx->id,
+                          ctx->peer, &sd_buf);
     krb5_data_free(&buf);
     if (ret)
        goto out;
@@ -878,7 +915,8 @@ pk_verify_host(krb5_context context,
        hx509_octet_string_list list;
        int i;
 
-       ret = hx509_cert_find_subjectAltName_otherName(host->cert,
+       ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx,
+                                                      host->cert,
                                                       oid_id_pkinit_san(),
                                                       &list);
        if (ret) {
index 43fa3f5b45a385058358bdc0f53f7800a7977e40..bae28496aaf823405fbfa1b852e0f9f2e0045612 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: plugin.c 21702 2007-07-26 19:13:53Z lha $");
+RCSID("$Id: plugin.c 22033 2007-11-10 10:39:47Z lha $");
 #ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
@@ -117,11 +117,23 @@ loadlib(krb5_context context,
 }
 #endif /* HAVE_DLOPEN */
 
+/**
+ * Register a plugin symbol name of specific type.
+ * @param context a Keberos context
+ * @param type type of plugin symbol
+ * @param name name of plugin symbol
+ * @param symbol a pointer to the named symbol
+ * @return In case of error a non zero error com_err error is returned
+ * and the Kerberos error string is set.
+ *
+ * @ingroup krb5_support
+ */
+
 krb5_error_code
-_krb5_plugin_register(krb5_context context,
-                     enum krb5_plugin_type type,
-                     const char *name, 
-                     void *symbol)
+krb5_plugin_register(krb5_context context,
+                    enum krb5_plugin_type type,
+                    const char *name, 
+                    void *symbol)
 {
     struct plugin *e;
 
@@ -250,4 +262,3 @@ _krb5_plugin_free(struct krb5_plugin *list)
        list = next;
     }
 }
-
index c1a29d266b636c01372d5e813a8d556eba11d4f6..cdad4771153ede8d0361120441d71118eab6a8f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
  * SUCH DAMAGE. 
  */
 
+/**
+ * @page page_principal The principal handing functions.
+ *
+ * A Kerberos principal is a email address looking string that
+ * contains to parts separeted by a @.  The later part is the kerbero
+ * realm the principal belongs to and the former is a list of 0 or
+ * more components. For example 
+ * @verbatim
+lha@SU.SE
+host/hummel.it.su.se@SU.SE
+host/admin@H5L.ORG
+@endverbatim
+ *
+ * See the library functions here: @ref krb5_principal
+ */
+
 #include "krb5_locl.h"
 #ifdef HAVE_RES_SEARCH
 #define USE_RESOLVER
@@ -41,7 +57,7 @@
 #include <fnmatch.h>
 #include "resolve.h"
 
-RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $");
+RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $");
 
 #define princ_num_comp(P) ((P)->name.name_string.len)
 #define princ_type(P) ((P)->name.name_type)
@@ -49,6 +65,21 @@ RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $");
 #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)])
 #define princ_realm(P) ((P)->realm)
 
+/**
+ * Frees a Kerberos principal allocated by the library with
+ * krb5_parse_name(), krb5_make_principal() or any other related
+ * principal functions.
+ *
+ * @param context A Kerberos context.
+ * @param p a principal to free.
+ *
+ * @return An krb5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5_principal
+ */
+
+
+
 void KRB5_LIB_FUNCTION
 krb5_free_principal(krb5_context context,
                    krb5_principal p)
@@ -804,7 +835,7 @@ krb5_425_conv_principal_ext2(krb5_context context,
     char local_hostname[MAXHOSTNAMELEN];
 
     /* do the following: if the name is found in the
-       `v4_name_convert:host' part, is is assumed to be a `host' type
+       `v4_name_convert:host' part, is assumed to be a `host' type
        principal, and the instance is looked up in the
        `v4_instance_convert' part. if not found there the name is
        (optionally) looked up as a hostname, and if that doesn't yield
index 47b5df85b23b052ceb4be4201b2bfd440e12ab31..ed7a2ccc5278a4064a0de01b6b874025b497947c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_priv.c 21770 2007-08-01 04:04:33Z lha $");
+RCSID("$Id: rd_priv.c 21751 2007-07-31 20:42:20Z lha $");
 
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_priv(krb5_context context,
index 001b47f094dfa715f08088fd8f4f27ede13755c4..0f33b97164544c426797646172ea41ed5764d84b 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_req.c 21004 2007-06-08 01:53:10Z lha $");
+RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $");
 
 static krb5_error_code
 decrypt_tkt_enc_part (krb5_context context,
@@ -137,7 +137,7 @@ check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc)
     krb5_error_code ret;
            
     /* 
-     * Windows 2000 and 2003 uses this inside their TGT so its normaly
+     * Windows 2000 and 2003 uses this inside their TGT so it's normaly
      * not seen by others, however, samba4 joined with a Windows AD as
      * a Domain Controller gets exposed to this.
      */
@@ -512,13 +512,13 @@ krb5_verify_ap_req2(krb5_context context,
  *
  */
 
-struct krb5_rd_req_in_ctx {
+struct krb5_rd_req_in_ctx_data {
     krb5_keytab keytab;
     krb5_keyblock *keyblock;
-    krb5_boolean no_pac_check;
+    krb5_boolean check_pac;
 };
 
-struct krb5_rd_req_out_ctx {
+struct krb5_rd_req_out_ctx_data {
     krb5_keyblock *keyblock;
     krb5_flags ap_req_options;
     krb5_ticket *ticket;
@@ -536,6 +536,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx)
        krb5_set_error_string(context, "out of memory");
        return ENOMEM;
     }
+    (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0;
     return 0;
 }
 
@@ -548,12 +549,24 @@ krb5_rd_req_in_set_keytab(krb5_context context,
     return 0;
 }
 
+/**
+ * Set if krb5_rq_red() is going to check the Windows PAC or not
+ * 
+ * @param context Keberos 5 context.
+ * @param in krb5_rd_req_in_ctx to check the option on.
+ * @param flag flag to select if to check the pac (TRUE) or not (FALSE).
+ *
+ * @return Kerberos 5 error code, see krb5_get_error_message().
+ *
+ * @ingroup krb5
+ */
+
 krb5_error_code KRB5_LIB_FUNCTION
 krb5_rd_req_in_set_pac_check(krb5_context context, 
                             krb5_rd_req_in_ctx in,
                             krb5_boolean flag)
 {
-    in->no_pac_check = !flag;
+    in->check_pac = flag;
     return 0;
 }
 
@@ -826,20 +839,21 @@ krb5_rd_req_ctx(krb5_context context,
            goto out;
     }
 
-    ret = krb5_verify_ap_req(context,
-                            auth_context,
-                            &ap_req,
-                            server,
-                            o->keyblock,
-                            0,
-                            &o->ap_req_options,
-                            &o->ticket);
+    ret = krb5_verify_ap_req2(context,
+                             auth_context,
+                             &ap_req,
+                             server,
+                             o->keyblock,
+                             0,
+                             &o->ap_req_options,
+                             &o->ticket,
+                             KRB5_KU_AP_REQ_AUTH);
 
     if (ret)
        goto out;
 
     /* If there is a PAC, verify its server signature */
-    if (inctx->no_pac_check == FALSE) {
+    if (inctx->check_pac) {
        krb5_pac pac;
        krb5_data data;
 
index c1a4df2b01c8766993b8aac53bbf815d2b060f9d..2582a615c052b749f2be94547e137c0c76f3339a 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: send_to_kdc.c 21062 2007-06-12 17:58:57Z lha $");
+RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $");
 
 struct send_to_kdc {
     krb5_send_to_kdc_func func;
@@ -448,7 +448,7 @@ krb5_set_send_to_kdc_func(krb5_context context,
     return 0;
 }
 
-struct krb5_sendto_ctx {
+struct krb5_sendto_ctx_data {
     int flags;
     int type;
     krb5_sendto_ctx_func func;
index 4abcf44a43ac36b7c96272aa1eab8f0d926f78c9..c9cbbb5cef3327b0077db1a44e16e69e72c4fa50 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id: store.c 20529 2007-04-22 14:28:19Z lha $");
+RCSID("$Id: store.c 22071 2007-11-14 20:04:50Z lha $");
 
 #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V))
 #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE)
@@ -838,8 +838,8 @@ krb5_ret_creds(krb5_storage *sp, krb5_creds *creds)
     if(ret) goto cleanup;
     /*
      * Runtime detect the what is the higher bits of the bitfield. If
-     * any of the higher bits are set in the input data, its either a
-     * new ticket flag (and this code need to be removed), or its a
+     * any of the higher bits are set in the input data, it's either a
+     * new ticket flag (and this code need to be removed), or it's a
      * MIT cache (or new Heimdal cache), lets change it to our current
      * format.
      */
@@ -993,8 +993,8 @@ krb5_ret_creds_tag(krb5_storage *sp,
     if(ret) goto cleanup;
     /*
      * Runtime detect the what is the higher bits of the bitfield. If
-     * any of the higher bits are set in the input data, its either a
-     * new ticket flag (and this code need to be removed), or its a
+     * any of the higher bits are set in the input data, it's either a
+     * new ticket flag (and this code need to be removed), or it's a
      * MIT cache (or new Heimdal cache), lets change it to our current
      * format.
      */
index 07acdd1a00b7f9fe9eff1d534e05c7e059d0cca5..c38c1b53c3a5f98f9e6334d39f8d38f89704fe00 100644 (file)
@@ -34,7 +34,7 @@
 #include "krb5_locl.h"
 #include "store-int.h"
 
-RCSID("$Id: store_emem.c 13863 2004-05-25 21:46:46Z lha $");
+RCSID("$Id: store_emem.c 22574 2008-02-05 20:31:55Z lha $");
 
 typedef struct emem_storage{
     unsigned char *base;
@@ -115,13 +115,28 @@ emem_free(krb5_storage *sp)
 krb5_storage * KRB5_LIB_FUNCTION
 krb5_storage_emem(void)
 {
-    krb5_storage *sp = malloc(sizeof(krb5_storage));
-    emem_storage *s = malloc(sizeof(*s));
+    krb5_storage *sp;
+    emem_storage *s;
+
+    sp = malloc(sizeof(krb5_storage));
+    if (sp == NULL)
+       return NULL;
+
+    s = malloc(sizeof(*s));
+    if (s == NULL) {
+       free(sp);
+       return NULL;
+    }
     sp->data = s;
     sp->flags = 0;
     sp->eof_code = HEIM_ERR_EOF;
     s->size = 1024;
     s->base = malloc(s->size);
+    if (s->base == NULL) {
+       free(sp);
+       free(s);
+       return NULL;
+    }
     s->len = 0;
     s->ptr = s->base;
     sp->fetch = emem_fetch;
index 7f5498f5921c62ee0abade98b1b0100311c58126..9b67ecc04f26181e9859a23fd64441b17be9bdd6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: transited.c 17043 2006-04-10 10:26:35Z lha $");
+RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $");
 
 /* this is an attempt at one of the most horrible `compression'
    schemes that has ever been invented; it's so amazingly brain-dead
@@ -87,6 +87,10 @@ make_path(krb5_context context, struct tr_realm *r,
            if(strcmp(p, to) == 0)
                break;
            tmp = calloc(1, sizeof(*tmp));
+           if(tmp == NULL){
+               krb5_set_error_string (context, "malloc: out of memory");
+               return ENOMEM;
+           }
            tmp->next = path;
            path = tmp;
            path->realm = strdup(p);
@@ -107,6 +111,10 @@ make_path(krb5_context context, struct tr_realm *r,
            if(strncmp(to, from, p - from) == 0)
                break;
            tmp = calloc(1, sizeof(*tmp));
+           if(tmp == NULL){
+               krb5_set_error_string (context, "malloc: out of memory");
+               return ENOMEM;
+           }
            tmp->next = path;
            path = tmp;
            path->realm = malloc(p - from + 1);
@@ -277,6 +285,10 @@ decode_realms(krb5_context context,
        }
        if(tr[i] == ','){
            tmp = malloc(tr + i - start + 1);
+           if(tmp == NULL){
+               krb5_set_error_string (context, "malloc: out of memory");
+               return ENOMEM;
+           }
            memcpy(tmp, start, tr + i - start);
            tmp[tr + i - start] = '\0';
            r = make_realm(tmp);
@@ -290,6 +302,11 @@ decode_realms(krb5_context context,
        }
     }
     tmp = malloc(tr + i - start + 1);
+    if(tmp == NULL){
+       free(*realms);
+       krb5_set_error_string (context, "malloc: out of memory");
+       return ENOMEM;
+    }
     memcpy(tmp, start, tr + i - start);
     tmp[tr + i - start] = '\0';
     r = make_realm(tmp);
index 3f99df6391c4647d108519293667df588cdeb976..37b1e35dd18833adcce07bcf12dcfe75a58ff29a 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: v4_glue.c 21572 2007-07-16 05:13:08Z lha $");
+RCSID("$Id: v4_glue.c 22071 2007-11-14 20:04:50Z lha $");
 
 #include "krb5-v4compat.h"
 
@@ -599,7 +599,7 @@ _krb5_krb_cr_err_reply(krb5_context context,
     RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error);
     RCHECK(ret, put_nir(sp, name, inst, realm), error);
     RCHECK(ret, krb5_store_int32(sp, time_ws), error);
-    /* If its a Kerberos 4 error-code, remove the et BASE */
+    /* If it is a Kerberos 4 error-code, remove the et BASE */
     if (e >= ERROR_TABLE_BASE_krb && e <= ERROR_TABLE_BASE_krb + 255)
        e -= ERROR_TABLE_BASE_krb;
     RCHECK(ret, krb5_store_int32(sp, e), error);
index 438ba2b94d1a8f1019b436ce7cc26e8a06c1aa79..bc64791b4396a00cd5221ee7b6937e5656bf9cb9 100644 (file)
@@ -43,7 +43,7 @@ heim_ntlm_calculate_ntlm2_sess (
 
 int
 heim_ntlm_decode_targetinfo (
-       struct ntlm_buf */*data*/,
+       const struct ntlm_buf */*data*/,
        int /*ucs2*/,
        struct ntlm_targetinfo */*ti*/);
 
@@ -65,7 +65,7 @@ heim_ntlm_decode_type3 (
 
 int
 heim_ntlm_encode_targetinfo (
-       struct ntlm_targetinfo */*ti*/,
+       const struct ntlm_targetinfo */*ti*/,
        int /*ucs2*/,
        struct ntlm_buf */*data*/);
 
@@ -76,14 +76,17 @@ heim_ntlm_encode_type1 (
 
 int
 heim_ntlm_encode_type2 (
-       struct ntlm_type2 */*type2*/,
+       const struct ntlm_type2 */*type2*/,
        struct ntlm_buf */*data*/);
 
 int
 heim_ntlm_encode_type3 (
-       struct ntlm_type3 */*type3*/,
+       const struct ntlm_type3 */*type3*/,
        struct ntlm_buf */*data*/);
 
+void
+heim_ntlm_free_buf (struct ntlm_buf */*p*/);
+
 void
 heim_ntlm_free_targetinfo (struct ntlm_targetinfo */*ti*/);
 
index 1c1afe1eb1fd0f59aa55550f7a13e58b000dde66..09d2205fd2133a33e9925abea6993b80c29e363b 100644 (file)
  * SUCH DAMAGE. 
  */
 
-/* $Id: heimntlm.h 19469 2006-12-20 07:28:37Z lha $ */
+/* $Id: heimntlm.h 22376 2007-12-28 18:38:23Z lha $ */
 
 #ifndef HEIM_NTLM_H
 #define HEIM_NTLM_H
 
+/**
+ * Buffer for storing data in the NTLM library. When filled in by the
+ * library it should be freed with heim_ntlm_free_buf().
+ */
 struct ntlm_buf {
-    size_t length;
-    void *data;
+    size_t length; /**< length buffer data */
+    void *data; /**< pointer to the data itself */
 };
 
 #define NTLM_NEG_UNICODE               0x00000001
+#define NTLM_NEG_TARGET                        0x00000004
 #define NTLM_NEG_SIGN                  0x00000010
 #define NTLM_NEG_SEAL                  0x00000020
 #define NTLM_NEG_NTLM                  0x00000200
@@ -52,42 +57,66 @@ struct ntlm_buf {
 #define NTLM_NEG_ALWAYS_SIGN           0x00008000
 #define NTLM_NEG_NTLM2_SESSION         0x00080000
 
-#define NTLM_NEG_TARGET_DOMAIN         0x00010000
+#define NTLM_TARGET_DOMAIN             0x00010000
+#define NTLM_TARGET_SERVER             0x00020000
 #define NTLM_ENC_128                   0x20000000
 #define NTLM_NEG_KEYEX                 0x40000000
 
+/**
+ * Struct for the NTLM target info, the strings is assumed to be in
+ * UTF8.  When filled in by the library it should be freed with
+ * heim_ntlm_free_targetinfo().
+ */
 struct ntlm_targetinfo {
-    char *servername;
-    char *domainname;
-    char *dnsdomainname;
-    char *dnsservername;
+    char *servername; /**< */
+    char *domainname; /**< */
+    char *dnsdomainname; /**< */
+    char *dnsservername; /**< */
 };
 
+/**
+ * Struct for the NTLM type1 message info, the strings is assumed to
+ * be in UTF8.  When filled in by the library it should be freed with
+ * heim_ntlm_free_type1().
+ */
+
 struct ntlm_type1 {
-    uint32_t flags;
-    char *domain;
-    char *hostname;
-    uint32_t os[2];
+    uint32_t flags; /**< */
+    char *domain; /**< */
+    char *hostname; /**< */
+    uint32_t os[2]; /**< */
 };
 
+/**
+ * Struct for the NTLM type2 message info, the strings is assumed to
+ * be in UTF8.  When filled in by the library it should be freed with
+ * heim_ntlm_free_type2().
+ */
+
 struct ntlm_type2 {
-    uint32_t flags;
-    char *targetname;
-    struct ntlm_buf targetinfo;
-    unsigned char challange[8];
-    uint32_t context[2];
-    uint32_t os[2];
+    uint32_t flags; /**< */
+    char *targetname; /**< */
+    struct ntlm_buf targetinfo; /**< */
+    unsigned char challange[8]; /**< */
+    uint32_t context[2]; /**< */
+    uint32_t os[2]; /**< */
 };
 
+/**
+ * Struct for the NTLM type3 message info, the strings is assumed to
+ * be in UTF8.  When filled in by the library it should be freed with
+ * heim_ntlm_free_type3().
+ */
+
 struct ntlm_type3 {
-    uint32_t flags;
-    char *username;
-    char *targetname;
-    struct ntlm_buf lm;
-    struct ntlm_buf ntlm;
-    struct ntlm_buf sessionkey;
-    char *ws;
-    uint32_t os[2];
+    uint32_t flags; /**< */
+    char *username; /**< */
+    char *targetname; /**< */
+    struct ntlm_buf lm; /**< */
+    struct ntlm_buf ntlm; /**< */
+    struct ntlm_buf sessionkey; /**< */
+    char *ws; /**< */
+    uint32_t os[2]; /**< */
 };
 
 #include <heimntlm-protos.h>
index 671bf329e86c36f7157037547b3fef1e737dea2f..f3dccfaca165886f48f06edb9fa3a34011553a38 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <config.h>
 
-RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
+RCSID("$Id: ntlm.c 22370 2007-12-28 16:12:01Z lha $");
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -51,12 +51,37 @@ RCSID("$Id: ntlm.c 21604 2007-07-17 06:48:55Z lha $");
 
 #include <heimntlm.h>
 
-
-/*
- * Source of NTLM information:
- * http://davenport.sourceforge.net/ntlm.html
+/*! \mainpage Heimdal NTLM library
+ *
+ * \section intro Introduction
+ *
+ * Heimdal libheimntlm library is a implementation of the NTLM
+ * protocol, both version 1 and 2. The GSS-API mech that uses this
+ * library adds support for transport encryption and integrity
+ * checking.
+ * 
+ * NTLM is a protocol for mutual authentication, its still used in
+ * many protocol where Kerberos is not support, one example is
+ * EAP/X802.1x mechanism LEAP from Microsoft and Cisco.
+ *
+ * This is a support library for the core protocol, its used in
+ * Heimdal to implement and GSS-API mechanism. There is also support
+ * in the KDC to do remote digest authenticiation, this to allow
+ * services to authenticate users w/o direct access to the users ntlm
+ * hashes (same as Kerberos arcfour enctype hashes).
+ *
+ * More information about the NTLM protocol can found here
+ * http://davenport.sourceforge.net/ntlm.html .
+ * 
+ * The Heimdal projects web page: http://www.h5l.org/
  */
 
+/** @defgroup ntlm_core Heimdal NTLM library 
+ * 
+ * The NTLM core functions implement the string2key generation
+ * function, message encode and decode function, and the hash function
+ * functions.
+ */
 
 struct sec_buffer {
     uint16_t length;
@@ -73,8 +98,16 @@ static const unsigned char ntlmsigature[8] = "NTLMSSP\x00";
 #define CHECK(f, e)                                                    \
     do { ret = f ; if (ret != (e)) { ret = EINVAL; goto out; } } while(0)
 
-static void
-_ntlm_free_buf(struct ntlm_buf *p)
+/**
+ * heim_ntlm_free_buf frees the ntlm buffer
+ *
+ * @param p buffer to be freed
+ *
+ * @ingroup ntlm_core
+ */
+
+void
+heim_ntlm_free_buf(struct ntlm_buf *p)
 {
     if (p->data)
        free(p->data);
@@ -96,7 +129,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
     buf->length = len * 2;
     buf->data = malloc(buf->length);
     if (buf->data == NULL && len != 0) {
-       _ntlm_free_buf(buf);
+       heim_ntlm_free_buf(buf);
        return ENOMEM;
     }
 
@@ -104,7 +137,7 @@ ascii2ucs2le(const char *string, int up, struct ntlm_buf *buf)
     for (i = 0; i < len; i++) {
        unsigned char t = (unsigned char)string[i];
        if (t & 0x80) {
-           _ntlm_free_buf(buf);
+           heim_ntlm_free_buf(buf);
            return EINVAL;
        }
        if (up)
@@ -201,7 +234,7 @@ put_string(krb5_storage *sp, int ucs2, const char *s)
 
     CHECK(krb5_storage_write(sp, buf.data, buf.length), buf.length);
     if (ucs2)
-       _ntlm_free_buf(&buf);
+       heim_ntlm_free_buf(&buf);
     ret = 0;
 out:
     return ret;
@@ -226,7 +259,7 @@ out:
 }
 
 static krb5_error_code
-put_buf(krb5_storage *sp, struct ntlm_buf *buf)
+put_buf(krb5_storage *sp, const struct ntlm_buf *buf)
 {
     krb5_error_code ret;
     CHECK(krb5_storage_write(sp, buf->data, buf->length), buf->length);
@@ -235,8 +268,12 @@ out:
     return ret;
 }
 
-/*
+/**
+ * Frees the ntlm_targetinfo message
+ *
+ * @param ti targetinfo to be freed
  *
+ * @ingroup ntlm_core
  */
 
 void
@@ -260,8 +297,22 @@ out:
     return ret;
 }
 
+/**
+ * Encodes a ntlm_targetinfo message.
+ *
+ * @param ti the ntlm_targetinfo message to encode.
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
 int
-heim_ntlm_encode_targetinfo(struct ntlm_targetinfo *ti,
+heim_ntlm_encode_targetinfo(const struct ntlm_targetinfo *ti,
                            int ucs2, 
                            struct ntlm_buf *data)
 {
@@ -299,16 +350,34 @@ out:
     return ret;
 }
 
+/**
+ * Decodes an NTLM targetinfo message
+ *
+ * @param data input data buffer with the encode NTLM targetinfo message
+ * @param ucs2 if the strings should be encoded with ucs2 (selected by flag in message).
+ * @param ti the decoded target info, should be freed with heim_ntlm_free_targetinfo().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
 int
-heim_ntlm_decode_targetinfo(struct ntlm_buf *data, int ucs2,
+heim_ntlm_decode_targetinfo(const struct ntlm_buf *data,
+                           int ucs2,
                            struct ntlm_targetinfo *ti)
 {
     memset(ti, 0, sizeof(*ti));
     return 0;
 }
 
-/*
- * encoder/decoder type1 messages
+/**
+ * Frees the ntlm_type1 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
  */
 
 void
@@ -367,6 +436,19 @@ out:
     return ret;
 }
 
+/**
+ * Encodes an ntlm_type1 message.
+ *
+ * @param type1 the ntlm_type1 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
 int
 heim_ntlm_encode_type1(const struct ntlm_type1 *type1, struct ntlm_buf *data)
 {
@@ -435,8 +517,12 @@ out:
     return ret;
 }
 
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type2 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
  */
 
 void
@@ -444,7 +530,7 @@ heim_ntlm_free_type2(struct ntlm_type2 *data)
 {
     if (data->targetname)
        free(data->targetname);
-    _ntlm_free_buf(&data->targetinfo);
+    heim_ntlm_free_buf(&data->targetinfo);
     memset(data, 0, sizeof(*data));
 }
 
@@ -499,8 +585,21 @@ out:
     return ret;
 }
 
+/**
+ * Encodes an ntlm_type2 message.
+ *
+ * @param type2 the ntlm_type2 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
 int
-heim_ntlm_encode_type2(struct ntlm_type2 *type2, struct ntlm_buf *data)
+heim_ntlm_encode_type2(const struct ntlm_type2 *type2, struct ntlm_buf *data)
 {
     struct sec_buffer targetname, targetinfo;
     krb5_error_code ret;
@@ -562,22 +661,26 @@ out:
     return ret;
 }
 
-/*
- * encoder/decoder type 2 messages
+/**
+ * Frees the ntlm_type3 message
+ *
+ * @param data message to be freed
+ *
+ * @ingroup ntlm_core
  */
 
 void
 heim_ntlm_free_type3(struct ntlm_type3 *data)
 {
-    _ntlm_free_buf(&data->lm);
-    _ntlm_free_buf(&data->ntlm);
+    heim_ntlm_free_buf(&data->lm);
+    heim_ntlm_free_buf(&data->ntlm);
     if (data->targetname)
        free(data->targetname);
     if (data->username)
        free(data->username);
     if (data->ws)
        free(data->ws);
-    _ntlm_free_buf(&data->sessionkey);
+    heim_ntlm_free_buf(&data->sessionkey);
     memset(data, 0, sizeof(*data));
 }
 
@@ -629,7 +732,7 @@ heim_ntlm_decode_type3(const struct ntlm_buf *buf,
     CHECK(ret_buf(in, &ntlm, &type3->ntlm), 0);
     CHECK(ret_string(in, ucs2, &target, &type3->targetname), 0);
     CHECK(ret_string(in, ucs2, &username, &type3->username), 0);
-    CHECK(ret_string(in, ucs2, &username, &type3->ws), 0);
+    CHECK(ret_string(in, ucs2, &ws, &type3->ws), 0);
     if (sessionkey.offset)
        CHECK(ret_buf(in, &sessionkey, &type3->sessionkey), 0);
 
@@ -641,8 +744,21 @@ out:
     return ret;
 }
 
+/**
+ * Encodes an ntlm_type3 message.
+ *
+ * @param type3 the ntlm_type3 message to encode.
+ * @param data is the return buffer with the encoded message, should be
+ * freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
+ */
+
 int
-heim_ntlm_encode_type3(struct ntlm_type3 *type3, struct ntlm_buf *data)
+heim_ntlm_encode_type3(const struct ntlm_type3 *type3, struct ntlm_buf *data)
 {
     struct sec_buffer lm, ntlm, target, username, sessionkey, ws;
     krb5_error_code ret;
@@ -766,8 +882,16 @@ splitandenc(unsigned char *hash,
     memset(key, 0, sizeof(key));
 }
 
-/*
- * String-to-key function for NTLM
+/**
+ * Calculate the NTLM key, the password is assumed to be in UTF8.
+ *
+ * @param password password to calcute the key for.
+ * @param key calcuted key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
@@ -784,18 +908,28 @@ heim_ntlm_nt_key(const char *password, struct ntlm_buf *key)
 
     ret = ascii2ucs2le(password, 0, &buf);
     if (ret) {
-       _ntlm_free_buf(key);
+       heim_ntlm_free_buf(key);
        return ret;
     }
     MD4_Init(&ctx);
     MD4_Update(&ctx, buf.data, buf.length);
     MD4_Final(key->data, &ctx);
-    _ntlm_free_buf(&buf);
+    heim_ntlm_free_buf(&buf);
     return 0;
 }
 
-/*
+/**
  * Calculate NTLMv1 response hash
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param challange sent by the server
+ * @param answer calculated answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
@@ -823,8 +957,18 @@ heim_ntlm_calculate_ntlm1(void *key, size_t len,
     return 0;
 }
 
-/*
- * Calculate NTLMv1 master key
+/**
+ * Generates an NTLMv1 session random with assosited session master key.
+ *
+ * @param key the ntlm v1 key
+ * @param len length of key
+ * @param session generated session nonce, should be freed with heim_ntlm_free_buf().
+ * @param master calculated session master key, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
@@ -849,8 +993,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
     master->length = MD4_DIGEST_LENGTH;
     master->data = malloc(master->length);
     if (master->data == NULL) {
-       _ntlm_free_buf(master);
-       _ntlm_free_buf(session);
+       heim_ntlm_free_buf(master);
+       heim_ntlm_free_buf(session);
        return EINVAL;
     }
     
@@ -866,8 +1010,8 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
     }
     
     if (RAND_bytes(session->data, session->length) != 1) {
-       _ntlm_free_buf(master);
-       _ntlm_free_buf(session);
+       heim_ntlm_free_buf(master);
+       heim_ntlm_free_buf(session);
        return EINVAL;
     }
     
@@ -877,8 +1021,16 @@ heim_ntlm_build_ntlm1_master(void *key, size_t len,
     return 0;
 }
 
-/*
+/**
+ * Generates an NTLMv2 session key.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param ntlmv2 the ntlmv2 session key
  *
+ * @ingroup ntlm_core
  */
 
 void
@@ -932,8 +1084,22 @@ nt2unixtime(uint64_t t)
 }
 
 
-/*
+/**
  * Calculate NTLMv2 response
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
@@ -1020,8 +1186,23 @@ out:
 
 static const int authtimediff = 3600 * 2; /* 2 hours */
 
-/*
+/**
  * Verify NTLMv2 response.
+ *
+ * @param key the ntlm key
+ * @param len length of key
+ * @param username name of the user, as sent in the message, assumed to be in UTF8.
+ * @param target the name of the target, assumed to be in UTF8.
+ * @param now the time now (0 if the library should pick it up itself)
+ * @param serverchallange challange as sent by the server in the type2 message.
+ * @param answer ntlm response answer, should be freed with heim_ntlm_free_buf().
+ * @param infotarget infotarget as sent by the server in the type2 message.
+ * @param ntlmv2 calculated session key
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
@@ -1110,13 +1291,13 @@ heim_ntlm_verify_ntlm2(const void *key, size_t len,
     HMAC_CTX_cleanup(&c);
 
     if (memcmp(serveranswer, clientanswer, 16) != 0) {
-       _ntlm_free_buf(infotarget);
+       heim_ntlm_free_buf(infotarget);
        return EINVAL;
     }
 
     return 0;
 out:
-    _ntlm_free_buf(infotarget);
+    heim_ntlm_free_buf(infotarget);
     if (sp)
        krb5_storage_free(sp);
     return ret;
@@ -1125,6 +1306,17 @@ out:
 
 /*
  * Calculate the NTLM2 Session Response
+ *
+ * @param clnt_nonce client nonce
+ * @param svr_chal server challage
+ * @param ntlm2_hash ntlm hash
+ * @param lm The LM response, should be freed with heim_ntlm_free_buf().
+ * @param ntlm The NTLM response, should be freed with heim_ntlm_free_buf().
+ *
+ * @return In case of success 0 is return, an errors, a errno in what
+ * went wrong.
+ *
+ * @ingroup ntlm_core
  */
 
 int
index 4337d591c42efc1f288e5c39eab51473b7235ac4..325f3fa046ff84d23fe9a73ebd57a22494264608 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: print_version.c 19566 2006-12-29 16:00:16Z lha $");
+RCSID("$Id: print_version.c 22428 2008-01-13 09:58:05Z lha $");
 #endif
 #include "roken.h"
 
@@ -50,6 +50,6 @@ print_version(const char *progname)
     if(*package_list == '\0')
        package_list = "no version information";
     fprintf(stderr, "%s (%s)\n", progname, package_list);
-    fprintf(stderr, "Copyright 1995-2007 Kungliga Tekniska Högskolan\n");
+    fprintf(stderr, "Copyright 1995-2008 Kungliga Tekniska Högskolan\n");
     fprintf(stderr, "Send bug-reports to %s\n", PACKAGE_BUGREPORT);
 }
diff --git a/source/heimdal/lib/wind/bidi.c b/source/heimdal/lib/wind/bidi.c
new file mode 100644 (file)
index 0000000..fa62989
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "bidi_table.h"
+
+static int
+range_entry_cmp(const void *a, const void *b)
+{
+    const struct range_entry *ea = (const struct range_entry*)a;
+    const struct range_entry *eb = (const struct range_entry*)b;
+
+    if (ea->start >= eb->start && ea->start < eb->start + eb->len)
+       return 0;
+    return ea->start - eb->start;
+}
+
+static int
+is_ral(uint32_t cp)
+{
+    struct range_entry ee = {cp};
+    void *s = bsearch(&ee, _wind_ral_table, _wind_ral_table_size,
+                     sizeof(_wind_ral_table[0]),
+                     range_entry_cmp);
+    return s != NULL;
+}
+
+static int
+is_l(uint32_t cp)
+{
+    struct range_entry ee = {cp};
+    void *s = bsearch(&ee, _wind_l_table, _wind_l_table_size,
+                     sizeof(_wind_l_table[0]),
+                     range_entry_cmp);
+    return s != NULL;
+}
+
+int
+_wind_stringprep_testbidi(const uint32_t *in, size_t in_len, wind_profile_flags flags)
+{
+    size_t i;
+    unsigned ral = 0;
+    unsigned l   = 0;
+
+    if ((flags & (WIND_PROFILE_NAME|WIND_PROFILE_SASL)) == 0)
+       return 0;
+
+    for (i = 0; i < in_len; ++i) {
+       ral |= is_ral(in[i]);
+       l   |= is_l(in[i]);
+    }
+    if (ral) {
+       if (l)
+           return 1;
+       if (!is_ral(in[0]) || !is_ral(in[in_len - 1]))
+           return 1;
+    }
+    return 0;
+}
diff --git a/source/heimdal/lib/wind/bidi_table.c b/source/heimdal/lib/wind/bidi_table.c
new file mode 100644 (file)
index 0000000..34530b9
--- /dev/null
@@ -0,0 +1,410 @@
+/* bidi_table.c */
+/* Automatically generated at 2008-03-18T11:38:07.839291 */
+
+
+#include "bidi_table.h"
+
+const struct range_entry _wind_ral_table[] = {
+  {0x5be, 1},
+  {0x5c0, 1},
+  {0x5c3, 1},
+  {0x5d0, 0x1b},
+  {0x5f0, 0x5},
+  {0x61b, 1},
+  {0x61f, 1},
+  {0x621, 0x1a},
+  {0x640, 0xb},
+  {0x66d, 0x3},
+  {0x671, 0x65},
+  {0x6dd, 1},
+  {0x6e5, 0x2},
+  {0x6fa, 0x5},
+  {0x700, 0xe},
+  {0x710, 1},
+  {0x712, 0x1b},
+  {0x780, 0x26},
+  {0x7b1, 1},
+  {0x200f, 1},
+  {0xfb1d, 1},
+  {0xfb1f, 0xa},
+  {0xfb2a, 0xd},
+  {0xfb38, 0x5},
+  {0xfb3e, 1},
+  {0xfb40, 0x2},
+  {0xfb43, 0x2},
+  {0xfb46, 0x6c},
+  {0xfbd3, 0x16b},
+  {0xfd50, 0x40},
+  {0xfd92, 0x36},
+  {0xfdf0, 0xd},
+  {0xfe70, 0x5},
+  {0xfe76, 0x87},
+};
+
+const size_t _wind_ral_table_size = 34;
+
+const struct range_entry _wind_l_table[] = {
+  {0x41, 0x1a},
+  {0x61, 0x1a},
+  {0xaa, 1},
+  {0xb5, 1},
+  {0xba, 1},
+  {0xc0, 0x17},
+  {0xd8, 0x1f},
+  {0xf8, 0x129},
+  {0x222, 0x12},
+  {0x250, 0x5e},
+  {0x2b0, 0x9},
+  {0x2bb, 0x7},
+  {0x2d0, 0x2},
+  {0x2e0, 0x5},
+  {0x2ee, 1},
+  {0x37a, 1},
+  {0x386, 1},
+  {0x388, 0x3},
+  {0x38c, 1},
+  {0x38e, 0x14},
+  {0x3a3, 0x2c},
+  {0x3d0, 0x26},
+  {0x400, 0x83},
+  {0x48a, 0x45},
+  {0x4d0, 0x26},
+  {0x4f8, 0x2},
+  {0x500, 0x10},
+  {0x531, 0x26},
+  {0x559, 0x7},
+  {0x561, 0x27},
+  {0x589, 1},
+  {0x903, 1},
+  {0x905, 0x35},
+  {0x93d, 0x4},
+  {0x949, 0x4},
+  {0x950, 1},
+  {0x958, 0xa},
+  {0x964, 0xd},
+  {0x982, 0x2},
+  {0x985, 0x8},
+  {0x98f, 0x2},
+  {0x993, 0x16},
+  {0x9aa, 0x7},
+  {0x9b2, 1},
+  {0x9b6, 0x4},
+  {0x9be, 0x3},
+  {0x9c7, 0x2},
+  {0x9cb, 0x2},
+  {0x9d7, 1},
+  {0x9dc, 0x2},
+  {0x9df, 0x3},
+  {0x9e6, 0xc},
+  {0x9f4, 0x7},
+  {0xa05, 0x6},
+  {0xa0f, 0x2},
+  {0xa13, 0x16},
+  {0xa2a, 0x7},
+  {0xa32, 0x2},
+  {0xa35, 0x2},
+  {0xa38, 0x2},
+  {0xa3e, 0x3},
+  {0xa59, 0x4},
+  {0xa5e, 1},
+  {0xa66, 0xa},
+  {0xa72, 0x3},
+  {0xa83, 1},
+  {0xa85, 0x7},
+  {0xa8d, 1},
+  {0xa8f, 0x3},
+  {0xa93, 0x16},
+  {0xaaa, 0x7},
+  {0xab2, 0x2},
+  {0xab5, 0x5},
+  {0xabd, 0x4},
+  {0xac9, 1},
+  {0xacb, 0x2},
+  {0xad0, 1},
+  {0xae0, 1},
+  {0xae6, 0xa},
+  {0xb02, 0x2},
+  {0xb05, 0x8},
+  {0xb0f, 0x2},
+  {0xb13, 0x16},
+  {0xb2a, 0x7},
+  {0xb32, 0x2},
+  {0xb36, 0x4},
+  {0xb3d, 0x2},
+  {0xb40, 1},
+  {0xb47, 0x2},
+  {0xb4b, 0x2},
+  {0xb57, 1},
+  {0xb5c, 0x2},
+  {0xb5f, 0x3},
+  {0xb66, 0xb},
+  {0xb83, 1},
+  {0xb85, 0x6},
+  {0xb8e, 0x3},
+  {0xb92, 0x4},
+  {0xb99, 0x2},
+  {0xb9c, 1},
+  {0xb9e, 0x2},
+  {0xba3, 0x2},
+  {0xba8, 0x3},
+  {0xbae, 0x8},
+  {0xbb7, 0x3},
+  {0xbbe, 0x2},
+  {0xbc1, 0x2},
+  {0xbc6, 0x3},
+  {0xbca, 0x3},
+  {0xbd7, 1},
+  {0xbe7, 0xc},
+  {0xc01, 0x3},
+  {0xc05, 0x8},
+  {0xc0e, 0x3},
+  {0xc12, 0x17},
+  {0xc2a, 0xa},
+  {0xc35, 0x5},
+  {0xc41, 0x4},
+  {0xc60, 0x2},
+  {0xc66, 0xa},
+  {0xc82, 0x2},
+  {0xc85, 0x8},
+  {0xc8e, 0x3},
+  {0xc92, 0x17},
+  {0xcaa, 0xa},
+  {0xcb5, 0x5},
+  {0xcbe, 1},
+  {0xcc0, 0x5},
+  {0xcc7, 0x2},
+  {0xcca, 0x2},
+  {0xcd5, 0x2},
+  {0xcde, 1},
+  {0xce0, 0x2},
+  {0xce6, 0xa},
+  {0xd02, 0x2},
+  {0xd05, 0x8},
+  {0xd0e, 0x3},
+  {0xd12, 0x17},
+  {0xd2a, 0x10},
+  {0xd3e, 0x3},
+  {0xd46, 0x3},
+  {0xd4a, 0x3},
+  {0xd57, 1},
+  {0xd60, 0x2},
+  {0xd66, 0xa},
+  {0xd82, 0x2},
+  {0xd85, 0x12},
+  {0xd9a, 0x18},
+  {0xdb3, 0x9},
+  {0xdbd, 1},
+  {0xdc0, 0x7},
+  {0xdcf, 0x3},
+  {0xdd8, 0x8},
+  {0xdf2, 0x3},
+  {0xe01, 0x30},
+  {0xe32, 0x2},
+  {0xe40, 0x7},
+  {0xe4f, 0xd},
+  {0xe81, 0x2},
+  {0xe84, 1},
+  {0xe87, 0x2},
+  {0xe8a, 1},
+  {0xe8d, 1},
+  {0xe94, 0x4},
+  {0xe99, 0x7},
+  {0xea1, 0x3},
+  {0xea5, 1},
+  {0xea7, 1},
+  {0xeaa, 0x2},
+  {0xead, 0x4},
+  {0xeb2, 0x2},
+  {0xebd, 1},
+  {0xec0, 0x5},
+  {0xec6, 1},
+  {0xed0, 0xa},
+  {0xedc, 0x2},
+  {0xf00, 0x18},
+  {0xf1a, 0x1b},
+  {0xf36, 1},
+  {0xf38, 1},
+  {0xf3e, 0xa},
+  {0xf49, 0x22},
+  {0xf7f, 1},
+  {0xf85, 1},
+  {0xf88, 0x4},
+  {0xfbe, 0x8},
+  {0xfc7, 0x6},
+  {0xfcf, 1},
+  {0x1000, 0x22},
+  {0x1023, 0x5},
+  {0x1029, 0x2},
+  {0x102c, 1},
+  {0x1031, 1},
+  {0x1038, 1},
+  {0x1040, 0x18},
+  {0x10a0, 0x26},
+  {0x10d0, 0x29},
+  {0x10fb, 1},
+  {0x1100, 0x5a},
+  {0x115f, 0x44},
+  {0x11a8, 0x52},
+  {0x1200, 0x7},
+  {0x1208, 0x3f},
+  {0x1248, 1},
+  {0x124a, 0x4},
+  {0x1250, 0x7},
+  {0x1258, 1},
+  {0x125a, 0x4},
+  {0x1260, 0x27},
+  {0x1288, 1},
+  {0x128a, 0x4},
+  {0x1290, 0x1f},
+  {0x12b0, 1},
+  {0x12b2, 0x4},
+  {0x12b8, 0x7},
+  {0x12c0, 1},
+  {0x12c2, 0x4},
+  {0x12c8, 0x7},
+  {0x12d0, 0x7},
+  {0x12d8, 0x17},
+  {0x12f0, 0x1f},
+  {0x1310, 1},
+  {0x1312, 0x4},
+  {0x1318, 0x7},
+  {0x1320, 0x27},
+  {0x1348, 0x13},
+  {0x1361, 0x1c},
+  {0x13a0, 0x55},
+  {0x1401, 0x276},
+  {0x1681, 0x1a},
+  {0x16a0, 0x51},
+  {0x1700, 0xd},
+  {0x170e, 0x4},
+  {0x1720, 0x12},
+  {0x1735, 0x2},
+  {0x1740, 0x12},
+  {0x1760, 0xd},
+  {0x176e, 0x3},
+  {0x1780, 0x37},
+  {0x17be, 0x8},
+  {0x17c7, 0x2},
+  {0x17d4, 0x7},
+  {0x17dc, 1},
+  {0x17e0, 0xa},
+  {0x1810, 0xa},
+  {0x1820, 0x58},
+  {0x1880, 0x29},
+  {0x1e00, 0x9c},
+  {0x1ea0, 0x5a},
+  {0x1f00, 0x16},
+  {0x1f18, 0x6},
+  {0x1f20, 0x26},
+  {0x1f48, 0x6},
+  {0x1f50, 0x8},
+  {0x1f59, 1},
+  {0x1f5b, 1},
+  {0x1f5d, 1},
+  {0x1f5f, 0x1f},
+  {0x1f80, 0x35},
+  {0x1fb6, 0x7},
+  {0x1fbe, 1},
+  {0x1fc2, 0x3},
+  {0x1fc6, 0x7},
+  {0x1fd0, 0x4},
+  {0x1fd6, 0x6},
+  {0x1fe0, 0xd},
+  {0x1ff2, 0x3},
+  {0x1ff6, 0x7},
+  {0x200e, 1},
+  {0x2071, 1},
+  {0x207f, 1},
+  {0x2102, 1},
+  {0x2107, 1},
+  {0x210a, 0xa},
+  {0x2115, 1},
+  {0x2119, 0x5},
+  {0x2124, 1},
+  {0x2126, 1},
+  {0x2128, 1},
+  {0x212a, 0x4},
+  {0x212f, 0x3},
+  {0x2133, 0x7},
+  {0x213d, 0x3},
+  {0x2145, 0x5},
+  {0x2160, 0x24},
+  {0x2336, 0x45},
+  {0x2395, 1},
+  {0x249c, 0x4e},
+  {0x3005, 0x3},
+  {0x3021, 0x9},
+  {0x3031, 0x5},
+  {0x3038, 0x5},
+  {0x3041, 0x56},
+  {0x309d, 0x3},
+  {0x30a1, 0x5a},
+  {0x30fc, 0x4},
+  {0x3105, 0x28},
+  {0x3131, 0x5e},
+  {0x3190, 0x28},
+  {0x31f0, 0x2d},
+  {0x3220, 0x24},
+  {0x3260, 0x1c},
+  {0x327f, 0x32},
+  {0x32c0, 0xc},
+  {0x32d0, 0x2f},
+  {0x3300, 0x77},
+  {0x337b, 0x63},
+  {0x33e0, 0x1f},
+  {0x3400, 0x19b6},
+  {0x4e00, 0x51a6},
+  {0xa000, 0x48d},
+  {0xac00, 0x2ba4},
+  {0xd800, 0x222e},
+  {0xfa30, 0x3b},
+  {0xfb00, 0x7},
+  {0xfb13, 0x5},
+  {0xff21, 0x1a},
+  {0xff41, 0x1a},
+  {0xff66, 0x59},
+  {0xffc2, 0x6},
+  {0xffca, 0x6},
+  {0xffd2, 0x6},
+  {0xffda, 0x3},
+  {0x10300, 0x1f},
+  {0x10320, 0x4},
+  {0x10330, 0x1b},
+  {0x10400, 0x26},
+  {0x10428, 0x26},
+  {0x1d000, 0xf6},
+  {0x1d100, 0x27},
+  {0x1d12a, 0x3d},
+  {0x1d16a, 0x9},
+  {0x1d183, 0x2},
+  {0x1d18c, 0x1e},
+  {0x1d1ae, 0x30},
+  {0x1d400, 0x55},
+  {0x1d456, 0x47},
+  {0x1d49e, 0x2},
+  {0x1d4a2, 1},
+  {0x1d4a5, 0x2},
+  {0x1d4a9, 0x4},
+  {0x1d4ae, 0xc},
+  {0x1d4bb, 1},
+  {0x1d4bd, 0x4},
+  {0x1d4c2, 0x2},
+  {0x1d4c5, 0x41},
+  {0x1d507, 0x4},
+  {0x1d50d, 0x8},
+  {0x1d516, 0x7},
+  {0x1d51e, 0x1c},
+  {0x1d53b, 0x4},
+  {0x1d540, 0x5},
+  {0x1d546, 1},
+  {0x1d54a, 0x7},
+  {0x1d552, 0x152},
+  {0x1d6a8, 0x122},
+  {0x20000, 0xa6d7},
+  {0x2f800, 0x21e},
+  {0xf0000, 0xfffe},
+  {0x100000, 0xfffe},
+};
+
+const size_t _wind_l_table_size = 360;
+
diff --git a/source/heimdal/lib/wind/bidi_table.h b/source/heimdal/lib/wind/bidi_table.h
new file mode 100644 (file)
index 0000000..2e369f2
--- /dev/null
@@ -0,0 +1,21 @@
+/* bidi_table.h */
+/* Automatically generated at 2008-03-18T11:38:07.839121 */
+
+#ifndef BIDI_TABLE_H
+#define BIDI_TABLE_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct range_entry {
+  uint32_t start;
+  unsigned len;
+};
+
+extern const struct range_entry _wind_ral_table[];
+extern const struct range_entry _wind_l_table[];
+
+extern const size_t _wind_ral_table_size;
+extern const size_t _wind_l_table_size;
+
+#endif /* BIDI_TABLE_H */
diff --git a/source/heimdal/lib/wind/combining.c b/source/heimdal/lib/wind/combining.c
new file mode 100644 (file)
index 0000000..8481cab
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "combining_table.h"
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+    const struct translation *t1 = (const struct translation *)key;
+    const struct translation *t2 = (const struct translation *)data;
+
+    return t1->key - t2->key;
+}
+
+int
+_wind_combining_class(uint32_t code_point)
+{
+    struct translation ts = {code_point};
+    void *s = bsearch(&ts, _wind_combining_table, _wind_combining_table_size,
+                     sizeof(_wind_combining_table[0]),
+                     translation_cmp);
+    if (s != NULL) {
+       const struct translation *t = (const struct translation *)s;
+       return t->combining_class;
+    } else {
+       return 0;
+    }
+}
diff --git a/source/heimdal/lib/wind/combining_table.c b/source/heimdal/lib/wind/combining_table.c
new file mode 100644 (file)
index 0000000..7abd1cf
--- /dev/null
@@ -0,0 +1,362 @@
+/* combining_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.166082 */
+
+
+#include "combining_table.h"
+
+const struct translation _wind_combining_table[] = {
+{0x300, 230}, /* Mn */
+{0x301, 230}, /* Mn */
+{0x302, 230}, /* Mn */
+{0x303, 230}, /* Mn */
+{0x304, 230}, /* Mn */
+{0x305, 230}, /* Mn */
+{0x306, 230}, /* Mn */
+{0x307, 230}, /* Mn */
+{0x308, 230}, /* Mn */
+{0x309, 230}, /* Mn */
+{0x30a, 230}, /* Mn */
+{0x30b, 230}, /* Mn */
+{0x30c, 230}, /* Mn */
+{0x30d, 230}, /* Mn */
+{0x30e, 230}, /* Mn */
+{0x30f, 230}, /* Mn */
+{0x310, 230}, /* Mn */
+{0x311, 230}, /* Mn */
+{0x312, 230}, /* Mn */
+{0x313, 230}, /* Mn */
+{0x314, 230}, /* Mn */
+{0x315, 232}, /* Mn */
+{0x316, 220}, /* Mn */
+{0x317, 220}, /* Mn */
+{0x318, 220}, /* Mn */
+{0x319, 220}, /* Mn */
+{0x31a, 232}, /* Mn */
+{0x31b, 216}, /* Mn */
+{0x31c, 220}, /* Mn */
+{0x31d, 220}, /* Mn */
+{0x31e, 220}, /* Mn */
+{0x31f, 220}, /* Mn */
+{0x320, 220}, /* Mn */
+{0x321, 202}, /* Mn */
+{0x322, 202}, /* Mn */
+{0x323, 220}, /* Mn */
+{0x324, 220}, /* Mn */
+{0x325, 220}, /* Mn */
+{0x326, 220}, /* Mn */
+{0x327, 202}, /* Mn */
+{0x328, 202}, /* Mn */
+{0x329, 220}, /* Mn */
+{0x32a, 220}, /* Mn */
+{0x32b, 220}, /* Mn */
+{0x32c, 220}, /* Mn */
+{0x32d, 220}, /* Mn */
+{0x32e, 220}, /* Mn */
+{0x32f, 220}, /* Mn */
+{0x330, 220}, /* Mn */
+{0x331, 220}, /* Mn */
+{0x332, 220}, /* Mn */
+{0x333, 220}, /* Mn */
+{0x334, 1}, /* Mn */
+{0x335, 1}, /* Mn */
+{0x336, 1}, /* Mn */
+{0x337, 1}, /* Mn */
+{0x338, 1}, /* Mn */
+{0x339, 220}, /* Mn */
+{0x33a, 220}, /* Mn */
+{0x33b, 220}, /* Mn */
+{0x33c, 220}, /* Mn */
+{0x33d, 230}, /* Mn */
+{0x33e, 230}, /* Mn */
+{0x33f, 230}, /* Mn */
+{0x340, 230}, /* Mn */
+{0x341, 230}, /* Mn */
+{0x342, 230}, /* Mn */
+{0x343, 230}, /* Mn */
+{0x344, 230}, /* Mn */
+{0x345, 240}, /* Mn */
+{0x346, 230}, /* Mn */
+{0x347, 220}, /* Mn */
+{0x348, 220}, /* Mn */
+{0x349, 220}, /* Mn */
+{0x34a, 230}, /* Mn */
+{0x34b, 230}, /* Mn */
+{0x34c, 230}, /* Mn */
+{0x34d, 220}, /* Mn */
+{0x34e, 220}, /* Mn */
+{0x350, 230}, /* Mn */
+{0x351, 230}, /* Mn */
+{0x352, 230}, /* Mn */
+{0x353, 220}, /* Mn */
+{0x354, 220}, /* Mn */
+{0x355, 220}, /* Mn */
+{0x356, 220}, /* Mn */
+{0x357, 230}, /* Mn */
+{0x35d, 234}, /* Mn */
+{0x35e, 234}, /* Mn */
+{0x35f, 233}, /* Mn */
+{0x360, 234}, /* Mn */
+{0x361, 234}, /* Mn */
+{0x362, 233}, /* Mn */
+{0x363, 230}, /* Mn */
+{0x364, 230}, /* Mn */
+{0x365, 230}, /* Mn */
+{0x366, 230}, /* Mn */
+{0x367, 230}, /* Mn */
+{0x368, 230}, /* Mn */
+{0x369, 230}, /* Mn */
+{0x36a, 230}, /* Mn */
+{0x36b, 230}, /* Mn */
+{0x36c, 230}, /* Mn */
+{0x36d, 230}, /* Mn */
+{0x36e, 230}, /* Mn */
+{0x36f, 230}, /* Mn */
+{0x483, 230}, /* Mn */
+{0x484, 230}, /* Mn */
+{0x485, 230}, /* Mn */
+{0x486, 230}, /* Mn */
+{0x591, 220}, /* Mn */
+{0x592, 230}, /* Mn */
+{0x593, 230}, /* Mn */
+{0x594, 230}, /* Mn */
+{0x595, 230}, /* Mn */
+{0x596, 220}, /* Mn */
+{0x597, 230}, /* Mn */
+{0x598, 230}, /* Mn */
+{0x599, 230}, /* Mn */
+{0x59a, 222}, /* Mn */
+{0x59b, 220}, /* Mn */
+{0x59c, 230}, /* Mn */
+{0x59d, 230}, /* Mn */
+{0x59e, 230}, /* Mn */
+{0x59f, 230}, /* Mn */
+{0x5a0, 230}, /* Mn */
+{0x5a1, 230}, /* Mn */
+{0x5a3, 220}, /* Mn */
+{0x5a4, 220}, /* Mn */
+{0x5a5, 220}, /* Mn */
+{0x5a6, 220}, /* Mn */
+{0x5a7, 220}, /* Mn */
+{0x5a8, 230}, /* Mn */
+{0x5a9, 230}, /* Mn */
+{0x5aa, 220}, /* Mn */
+{0x5ab, 230}, /* Mn */
+{0x5ac, 230}, /* Mn */
+{0x5ad, 222}, /* Mn */
+{0x5ae, 228}, /* Mn */
+{0x5af, 230}, /* Mn */
+{0x5b0, 10}, /* Mn */
+{0x5b1, 11}, /* Mn */
+{0x5b2, 12}, /* Mn */
+{0x5b3, 13}, /* Mn */
+{0x5b4, 14}, /* Mn */
+{0x5b5, 15}, /* Mn */
+{0x5b6, 16}, /* Mn */
+{0x5b7, 17}, /* Mn */
+{0x5b8, 18}, /* Mn */
+{0x5b9, 19}, /* Mn */
+{0x5bb, 20}, /* Mn */
+{0x5bc, 21}, /* Mn */
+{0x5bd, 22}, /* Mn */
+{0x5bf, 23}, /* Mn */
+{0x5c1, 24}, /* Mn */
+{0x5c2, 25}, /* Mn */
+{0x5c4, 230}, /* Mn */
+{0x610, 230}, /* Mn */
+{0x611, 230}, /* Mn */
+{0x612, 230}, /* Mn */
+{0x613, 230}, /* Mn */
+{0x614, 230}, /* Mn */
+{0x615, 230}, /* Mn */
+{0x64b, 27}, /* Mn */
+{0x64c, 28}, /* Mn */
+{0x64d, 29}, /* Mn */
+{0x64e, 30}, /* Mn */
+{0x64f, 31}, /* Mn */
+{0x650, 32}, /* Mn */
+{0x651, 33}, /* Mn */
+{0x652, 34}, /* Mn */
+{0x653, 230}, /* Mn */
+{0x654, 230}, /* Mn */
+{0x655, 220}, /* Mn */
+{0x656, 220}, /* Mn */
+{0x657, 230}, /* Mn */
+{0x658, 230}, /* Mn */
+{0x670, 35}, /* Mn */
+{0x6d6, 230}, /* Mn */
+{0x6d7, 230}, /* Mn */
+{0x6d8, 230}, /* Mn */
+{0x6d9, 230}, /* Mn */
+{0x6da, 230}, /* Mn */
+{0x6db, 230}, /* Mn */
+{0x6dc, 230}, /* Mn */
+{0x6df, 230}, /* Mn */
+{0x6e0, 230}, /* Mn */
+{0x6e1, 230}, /* Mn */
+{0x6e2, 230}, /* Mn */
+{0x6e3, 220}, /* Mn */
+{0x6e4, 230}, /* Mn */
+{0x6e7, 230}, /* Mn */
+{0x6e8, 230}, /* Mn */
+{0x6ea, 220}, /* Mn */
+{0x6eb, 230}, /* Mn */
+{0x6ec, 230}, /* Mn */
+{0x6ed, 220}, /* Mn */
+{0x711, 36}, /* Mn */
+{0x730, 230}, /* Mn */
+{0x731, 220}, /* Mn */
+{0x732, 230}, /* Mn */
+{0x733, 230}, /* Mn */
+{0x734, 220}, /* Mn */
+{0x735, 230}, /* Mn */
+{0x736, 230}, /* Mn */
+{0x737, 220}, /* Mn */
+{0x738, 220}, /* Mn */
+{0x739, 220}, /* Mn */
+{0x73a, 230}, /* Mn */
+{0x73b, 220}, /* Mn */
+{0x73c, 220}, /* Mn */
+{0x73d, 230}, /* Mn */
+{0x73e, 220}, /* Mn */
+{0x73f, 230}, /* Mn */
+{0x740, 230}, /* Mn */
+{0x741, 230}, /* Mn */
+{0x742, 220}, /* Mn */
+{0x743, 230}, /* Mn */
+{0x744, 220}, /* Mn */
+{0x745, 230}, /* Mn */
+{0x746, 220}, /* Mn */
+{0x747, 230}, /* Mn */
+{0x748, 220}, /* Mn */
+{0x749, 230}, /* Mn */
+{0x74a, 230}, /* Mn */
+{0x93c, 7}, /* Mn */
+{0x94d, 9}, /* Mn */
+{0x951, 230}, /* Mn */
+{0x952, 220}, /* Mn */
+{0x953, 230}, /* Mn */
+{0x954, 230}, /* Mn */
+{0x9bc, 7}, /* Mn */
+{0x9cd, 9}, /* Mn */
+{0xa3c, 7}, /* Mn */
+{0xa4d, 9}, /* Mn */
+{0xabc, 7}, /* Mn */
+{0xacd, 9}, /* Mn */
+{0xb3c, 7}, /* Mn */
+{0xb4d, 9}, /* Mn */
+{0xbcd, 9}, /* Mn */
+{0xc4d, 9}, /* Mn */
+{0xc55, 84}, /* Mn */
+{0xc56, 91}, /* Mn */
+{0xcbc, 7}, /* Mn */
+{0xccd, 9}, /* Mn */
+{0xd4d, 9}, /* Mn */
+{0xdca, 9}, /* Mn */
+{0xe38, 103}, /* Mn */
+{0xe39, 103}, /* Mn */
+{0xe3a, 9}, /* Mn */
+{0xe48, 107}, /* Mn */
+{0xe49, 107}, /* Mn */
+{0xe4a, 107}, /* Mn */
+{0xe4b, 107}, /* Mn */
+{0xeb8, 118}, /* Mn */
+{0xeb9, 118}, /* Mn */
+{0xec8, 122}, /* Mn */
+{0xec9, 122}, /* Mn */
+{0xeca, 122}, /* Mn */
+{0xecb, 122}, /* Mn */
+{0xf18, 220}, /* Mn */
+{0xf19, 220}, /* Mn */
+{0xf35, 220}, /* Mn */
+{0xf37, 220}, /* Mn */
+{0xf39, 216}, /* Mn */
+{0xf71, 129}, /* Mn */
+{0xf72, 130}, /* Mn */
+{0xf74, 132}, /* Mn */
+{0xf7a, 130}, /* Mn */
+{0xf7b, 130}, /* Mn */
+{0xf7c, 130}, /* Mn */
+{0xf7d, 130}, /* Mn */
+{0xf80, 130}, /* Mn */
+{0xf82, 230}, /* Mn */
+{0xf83, 230}, /* Mn */
+{0xf84, 9}, /* Mn */
+{0xf86, 230}, /* Mn */
+{0xf87, 230}, /* Mn */
+{0xfc6, 220}, /* Mn */
+{0x1037, 7}, /* Mn */
+{0x1039, 9}, /* Mn */
+{0x1714, 9}, /* Mn */
+{0x1734, 9}, /* Mn */
+{0x17d2, 9}, /* Mn */
+{0x17dd, 230}, /* Mn */
+{0x18a9, 228}, /* Mn */
+{0x1939, 222}, /* Mn */
+{0x193a, 230}, /* Mn */
+{0x193b, 220}, /* Mn */
+{0x20d0, 230}, /* Mn */
+{0x20d1, 230}, /* Mn */
+{0x20d2, 1}, /* Mn */
+{0x20d3, 1}, /* Mn */
+{0x20d4, 230}, /* Mn */
+{0x20d5, 230}, /* Mn */
+{0x20d6, 230}, /* Mn */
+{0x20d7, 230}, /* Mn */
+{0x20d8, 1}, /* Mn */
+{0x20d9, 1}, /* Mn */
+{0x20da, 1}, /* Mn */
+{0x20db, 230}, /* Mn */
+{0x20dc, 230}, /* Mn */
+{0x20e1, 230}, /* Mn */
+{0x20e5, 1}, /* Mn */
+{0x20e6, 1}, /* Mn */
+{0x20e7, 230}, /* Mn */
+{0x20e8, 220}, /* Mn */
+{0x20e9, 230}, /* Mn */
+{0x20ea, 1}, /* Mn */
+{0x302a, 218}, /* Mn */
+{0x302b, 228}, /* Mn */
+{0x302c, 232}, /* Mn */
+{0x302d, 222}, /* Mn */
+{0x302e, 224}, /* Mn */
+{0x302f, 224}, /* Mn */
+{0x3099, 8}, /* Mn */
+{0x309a, 8}, /* Mn */
+{0xfb1e, 26}, /* Mn */
+{0xfe20, 230}, /* Mn */
+{0xfe21, 230}, /* Mn */
+{0xfe22, 230}, /* Mn */
+{0xfe23, 230}, /* Mn */
+{0x1d165, 216}, /* Mc */
+{0x1d166, 216}, /* Mc */
+{0x1d167, 1}, /* Mn */
+{0x1d168, 1}, /* Mn */
+{0x1d169, 1}, /* Mn */
+{0x1d16d, 226}, /* Mc */
+{0x1d16e, 216}, /* Mc */
+{0x1d16f, 216}, /* Mc */
+{0x1d170, 216}, /* Mc */
+{0x1d171, 216}, /* Mc */
+{0x1d172, 216}, /* Mc */
+{0x1d17b, 220}, /* Mn */
+{0x1d17c, 220}, /* Mn */
+{0x1d17d, 220}, /* Mn */
+{0x1d17e, 220}, /* Mn */
+{0x1d17f, 220}, /* Mn */
+{0x1d180, 220}, /* Mn */
+{0x1d181, 220}, /* Mn */
+{0x1d182, 220}, /* Mn */
+{0x1d185, 230}, /* Mn */
+{0x1d186, 230}, /* Mn */
+{0x1d187, 230}, /* Mn */
+{0x1d188, 230}, /* Mn */
+{0x1d189, 230}, /* Mn */
+{0x1d18a, 220}, /* Mn */
+{0x1d18b, 220}, /* Mn */
+{0x1d1aa, 230}, /* Mn */
+{0x1d1ab, 230}, /* Mn */
+{0x1d1ac, 230}, /* Mn */
+{0x1d1ad, 230}, /* Mn */
+
+};
+const size_t _wind_combining_table_size = 352;
diff --git a/source/heimdal/lib/wind/combining_table.h b/source/heimdal/lib/wind/combining_table.h
new file mode 100644 (file)
index 0000000..000af13
--- /dev/null
@@ -0,0 +1,18 @@
+/* combining_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.165877 */
+
+#ifndef COMBINING_TABLE_H
+#define COMBINING_TABLE_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct translation {
+  uint32_t key;
+  unsigned combining_class;    
+};
+
+extern const struct translation _wind_combining_table[];
+
+extern const size_t _wind_combining_table_size;
+#endif /* COMBINING_TABLE_H */
diff --git a/source/heimdal/lib/wind/errorlist.c b/source/heimdal/lib/wind/errorlist.c
new file mode 100644 (file)
index 0000000..9a65338
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "errorlist_table.h"
+
+static int
+error_entry_cmp(const void *a, const void *b)
+{
+    const struct error_entry *ea = (const struct error_entry*)a;
+    const struct error_entry *eb = (const struct error_entry*)b;
+
+    if (ea->start >= eb->start && ea->start < eb->start + eb->len)
+       return 0;
+    return ea->start - eb->start;
+}
+
+int
+_wind_stringprep_error(uint32_t cp, wind_profile_flags flags)
+{
+    struct error_entry ee = {cp};
+    const struct error_entry *s;
+
+    s = (const struct error_entry *)
+       bsearch(&ee, _wind_errorlist_table,
+               _wind_errorlist_table_size,
+               sizeof(_wind_errorlist_table[0]),
+               error_entry_cmp);
+    if (s == NULL)
+       return 0;
+    return (s->flags & flags);
+}
+
+int
+_wind_stringprep_prohibited(const uint32_t *in, size_t in_len,
+                           wind_profile_flags flags)
+{
+    unsigned i;
+
+    for (i = 0; i < in_len; ++i)
+       if (_wind_stringprep_error(in[i], flags))
+           return 1;
+    return 0;
+}
diff --git a/source/heimdal/lib/wind/errorlist_table.c b/source/heimdal/lib/wind/errorlist_table.c
new file mode 100644 (file)
index 0000000..5d5d8ca
--- /dev/null
@@ -0,0 +1,88 @@
+/* errorlist_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.266475 */
+
+
+#include "errorlist_table.h"
+
+const struct error_entry _wind_errorlist_table[] = {
+  {0x0, 0x20, WIND_PROFILE_SASL}, /* C.2.1: [CONTROL CHARACTERS] */
+  {0x7f, 0x1, WIND_PROFILE_SASL}, /* C.2.1: DELETE */
+  {0x80, 0x20, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: [CONTROL CHARACTERS] */
+  {0xa0, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: NO-BREAK SPACE */
+  {0x340, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: COMBINING GRAVE TONE MARK */
+  {0x341, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: COMBINING ACUTE TONE MARK */
+  {0x6dd, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ARABIC END OF AYAH */
+  {0x70f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: SYRIAC ABBREVIATION MARK */
+  {0x1680, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: OGHAM SPACE MARK */
+  {0x180e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: MONGOLIAN VOWEL SEPARATOR */
+  {0x2000, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EN QUAD */
+  {0x2001, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EM QUAD */
+  {0x2002, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EN SPACE */
+  {0x2003, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: EM SPACE */
+  {0x2004, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: THREE-PER-EM SPACE */
+  {0x2005, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: FOUR-PER-EM SPACE */
+  {0x2006, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: SIX-PER-EM SPACE */
+  {0x2007, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: FIGURE SPACE */
+  {0x2008, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: PUNCTUATION SPACE */
+  {0x2009, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: THIN SPACE */
+  {0x200a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: HAIR SPACE */
+  {0x200b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: ZERO WIDTH SPACE */
+  {0x200c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH NON-JOINER */
+  {0x200d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH JOINER */
+  {0x200e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT MARK */
+  {0x200f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT MARK */
+  {0x2028, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: LINE SEPARATOR */
+  {0x2029, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: PARAGRAPH SEPARATOR */
+  {0x202a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT EMBEDDING */
+  {0x202b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT EMBEDDING */
+  {0x202c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: POP DIRECTIONAL FORMATTING */
+  {0x202d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: LEFT-TO-RIGHT OVERRIDE */
+  {0x202e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: RIGHT-TO-LEFT OVERRIDE */
+  {0x202f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: NARROW NO-BREAK SPACE */
+  {0x205f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: MEDIUM MATHEMATICAL SPACE */
+  {0x2060, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: WORD JOINER */
+  {0x2061, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: FUNCTION APPLICATION */
+  {0x2062, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: INVISIBLE TIMES */
+  {0x2063, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: INVISIBLE SEPARATOR */
+  {0x206a, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.8,C.2.2: INHIBIT SYMMETRIC SWAPPING */
+  {0x206b, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: ACTIVATE SYMMETRIC SWAPPING */
+  {0x206c, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: INHIBIT ARABIC FORM SHAPING */
+  {0x206d, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: ACTIVATE ARABIC FORM SHAPING */
+  {0x206e, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: NATIONAL DIGIT SHAPES */
+  {0x206f, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.8: NOMINAL DIGIT SHAPES */
+  {0x2ff0, 0xc, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.7: [IDEOGRAPHIC DESCRIPTION CHARACTERS] */
+  {0x3000, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.1.2: IDEOGRAPHIC SPACE */
+  {0xd800, 0x800, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.5: [SURROGATE CODES] */
+  {0xe000, 0x1900, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 0] */
+  {0xfdd0, 0x20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xfeff, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: ZERO WIDTH NO-BREAK SPACE */
+  {0xfff9, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6,C.2.2: INTERLINEAR ANNOTATION ANCHOR */
+  {0xfffa, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: INTERLINEAR ANNOTATION SEPARATOR */
+  {0xfffb, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: INTERLINEAR ANNOTATION TERMINATOR */
+  {0xfffc, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.6: OBJECT REPLACEMENT CHARACTER */
+  {0xfffd, 0x1, WIND_PROFILE_LDAP|WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* rfc4518-error,C.6:  */
+  {0xfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x1d173, 0x8, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.2.2: [MUSICAL CONTROL CHARACTERS] */
+  {0x1fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x2fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x3fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x4fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x5fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x6fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x7fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x8fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x9fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xafffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xbfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xcfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xdfffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xe0001, 0x1, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.9: LANGUAGE TAG */
+  {0xe0020, 0x60, WIND_PROFILE_NAME|WIND_PROFILE_SASL}, /* C.9: [TAGGING CHARACTERS] */
+  {0xefffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0xf0000, 0xfffe, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 15] */
+  {0xffffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+  {0x100000, 0xfffe, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.3: [PRIVATE USE, PLANE 16] */
+  {0x10fffe, 0x2, WIND_PROFILE_NAME|WIND_PROFILE_LDAP|WIND_PROFILE_SASL}, /* C.4: [NONCHARACTER CODE POINTS] */
+};
+
+const size_t _wind_errorlist_table_size = 78;
diff --git a/source/heimdal/lib/wind/errorlist_table.h b/source/heimdal/lib/wind/errorlist_table.h
new file mode 100644 (file)
index 0000000..5fc9ddb
--- /dev/null
@@ -0,0 +1,19 @@
+/* errorlist_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.266305 */
+
+#ifndef ERRORLIST_TABLE_H
+#define ERRORLIST_TABLE_H 1
+
+#include "windlocl.h"
+
+struct error_entry {
+  uint32_t start;
+  unsigned len;
+  wind_profile_flags flags;
+};
+
+extern const struct error_entry _wind_errorlist_table[];
+
+extern const size_t _wind_errorlist_table_size;
+
+#endif /* ERRORLIST_TABLE_H */
diff --git a/source/heimdal/lib/wind/ldap.c b/source/heimdal/lib/wind/ldap.c
new file mode 100644 (file)
index 0000000..1ff681f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "windlocl.h"
+#include <assert.h>
+
+static int
+put_char(uint32_t *out, size_t *o, uint32_t c, size_t out_len)
+{
+    if (*o >= out_len)
+       return 1;
+    out[*o] = c;
+    (*o)++;
+    return 0;
+}
+
+int
+_wind_ldap_case_exact_attribute(const uint32_t *tmp,
+                               size_t olen, 
+                               uint32_t *out,
+                               size_t *out_len)
+{
+    size_t o = 0, i = 0;
+
+    if (olen == 0) {
+       *out_len = 0;
+       return 0;
+    }
+
+    if (put_char(out, &o, 0x20, *out_len))
+       return WIND_ERR_OVERRUN;
+    while(i < olen && tmp[i] == 0x20) /* skip initial spaces */
+       i++;
+       
+    while (i < olen) {
+       if (tmp[i] == 0x20) {
+           if (put_char(out, &o, 0x20, *out_len) ||
+               put_char(out, &o, 0x20, *out_len))
+               return WIND_ERR_OVERRUN;
+           while(i < olen && tmp[i] == 0x20) /* skip middle spaces */
+               i++;
+       } else {
+           if (put_char(out, &o, tmp[i++], *out_len))
+               return WIND_ERR_OVERRUN;
+       }           
+    }
+    assert(o > 0);
+
+    /* only one spaces at the end */
+    if (o == 1 && out[0] == 0x20)
+       o = 0;
+    else if (out[o - 1] == 0x20) {
+       if (out[o - 2] == 0x20)
+           o--;
+    } else
+       put_char(out, &o, 0x20, *out_len);
+
+    *out_len = o;
+
+    return 0;
+}
diff --git a/source/heimdal/lib/wind/map.c b/source/heimdal/lib/wind/map.c
new file mode 100644 (file)
index 0000000..ae6d10e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+#include <stdlib.h>
+
+#include "map_table.h"
+
+RCSID("$Id: map.c 22556 2008-02-01 16:38:46Z lha $");
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+    const struct translation *t1 = (const struct translation *)key;
+    const struct translation *t2 = (const struct translation *)data;
+
+    return t1->key - t2->key;
+}
+
+int
+_wind_stringprep_map(const uint32_t *in, size_t in_len,
+                    uint32_t *out, size_t *out_len,
+                    wind_profile_flags flags)
+{
+    unsigned i;
+    unsigned o = 0;
+
+    for (i = 0; i < in_len; ++i) {
+       struct translation ts = {in[i]};
+       const struct translation *s;
+
+       s = (const struct translation *)
+           bsearch(&ts, _wind_map_table, _wind_map_table_size,
+                   sizeof(_wind_map_table[0]),
+                   translation_cmp);
+       if (s != NULL && (s->flags & flags)) {
+           unsigned j;
+
+           for (j = 0; j < s->val_len; ++j) {
+               if (o >= *out_len)
+                   return WIND_ERR_OVERRUN;
+               out[o++] = _wind_map_table_val[s->val_offset + j];
+           }
+       } else {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+           out[o++] = in[i];
+
+       }
+    }
+    *out_len = o;
+    return 0;
+}
diff --git a/source/heimdal/lib/wind/map_table.c b/source/heimdal/lib/wind/map_table.c
new file mode 100644 (file)
index 0000000..e4dba94
--- /dev/null
@@ -0,0 +1,2613 @@
+/* map_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.353797 */
+
+
+#include "map_table.h"
+
+const struct translation _wind_map_table[] = {
+  {0x0, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x2, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x3, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x4, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x5, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x6, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x7, 0, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9, 1, 0, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xa, 1, 1, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xb, 1, 2, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xc, 1, 3, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xd, 1, 4, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xe, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xf, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x10, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x11, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x12, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x13, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x14, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x15, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x16, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x17, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x18, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x19, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1a, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1b, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1c, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1e, 0, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x20, 1, 5, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x41, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x43, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x44, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x45, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x46, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x47, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x48, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x49, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4f, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x50, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x51, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x52, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x55, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x56, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x57, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x58, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x59, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x5a, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x7f, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x80, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x81, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x82, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x83, 0, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x85, 1, 32, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x86, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x87, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x88, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x89, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8a, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8b, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8c, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8d, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8e, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x8f, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x90, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x91, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x92, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x93, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x94, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x95, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x96, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x97, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x98, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x99, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9a, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9b, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9c, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9d, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x9e, 0, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xa0, 1, 33, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0xad, 0, 34, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xb5, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc0, 1, 35, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc1, 1, 36, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc2, 1, 37, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc3, 1, 38, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc4, 1, 39, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc5, 1, 40, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc6, 1, 41, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc7, 1, 42, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc8, 1, 43, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xc9, 1, 44, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xca, 1, 45, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xcb, 1, 46, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xcc, 1, 47, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xcd, 1, 48, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xce, 1, 49, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xcf, 1, 50, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd0, 1, 51, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd1, 1, 52, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd2, 1, 53, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd3, 1, 54, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd4, 1, 55, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd5, 1, 56, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd6, 1, 57, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd8, 1, 58, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xd9, 1, 59, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xda, 1, 60, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xdb, 1, 61, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xdc, 1, 62, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xdd, 1, 63, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xde, 1, 64, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xdf, 2, 65, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x100, 1, 67, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x102, 1, 68, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x104, 1, 69, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x106, 1, 70, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x108, 1, 71, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10a, 1, 72, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10c, 1, 73, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10e, 1, 74, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x110, 1, 75, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x112, 1, 76, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x114, 1, 77, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x116, 1, 78, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x118, 1, 79, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x11a, 1, 80, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x11c, 1, 81, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x11e, 1, 82, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x120, 1, 83, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x122, 1, 84, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x124, 1, 85, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x126, 1, 86, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x128, 1, 87, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x12a, 1, 88, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x12c, 1, 89, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x12e, 1, 90, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x130, 2, 91, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x132, 1, 93, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x134, 1, 94, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x136, 1, 95, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x139, 1, 96, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x13b, 1, 97, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x13d, 1, 98, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x13f, 1, 99, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x141, 1, 100, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x143, 1, 101, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x145, 1, 102, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x147, 1, 103, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x149, 2, 104, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x14a, 1, 106, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x14c, 1, 107, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x14e, 1, 108, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x150, 1, 109, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x152, 1, 110, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x154, 1, 111, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x156, 1, 112, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x158, 1, 113, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x15a, 1, 114, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x15c, 1, 115, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x15e, 1, 116, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x160, 1, 117, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x162, 1, 118, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x164, 1, 119, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x166, 1, 120, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x168, 1, 121, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x16a, 1, 122, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x16c, 1, 123, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x16e, 1, 124, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x170, 1, 125, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x172, 1, 126, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x174, 1, 127, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x176, 1, 128, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x178, 1, 129, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x179, 1, 130, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x17b, 1, 131, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x17d, 1, 132, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x17f, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x181, 1, 133, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x182, 1, 134, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x184, 1, 135, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x186, 1, 136, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x187, 1, 137, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x189, 1, 138, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x18a, 1, 139, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x18b, 1, 140, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x18e, 1, 141, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x18f, 1, 142, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x190, 1, 143, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x191, 1, 144, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x193, 1, 145, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x194, 1, 146, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x196, 1, 147, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x197, 1, 148, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x198, 1, 149, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x19c, 1, 150, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x19d, 1, 151, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x19f, 1, 152, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a0, 1, 153, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a2, 1, 154, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a4, 1, 155, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a6, 1, 156, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a7, 1, 157, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1a9, 1, 158, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ac, 1, 159, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ae, 1, 160, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1af, 1, 161, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b1, 1, 162, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b2, 1, 163, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b3, 1, 164, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b5, 1, 165, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b7, 1, 166, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1b8, 1, 167, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1bc, 1, 168, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1c4, 1, 169, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1c5, 1, 169, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1c7, 1, 170, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1c8, 1, 170, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ca, 1, 171, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1cb, 1, 171, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1cd, 1, 172, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1cf, 1, 173, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d1, 1, 174, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d3, 1, 175, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d5, 1, 176, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d7, 1, 177, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d9, 1, 178, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1db, 1, 179, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1de, 1, 180, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e0, 1, 181, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e2, 1, 182, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e4, 1, 183, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e6, 1, 184, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e8, 1, 185, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea, 1, 186, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec, 1, 187, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee, 1, 188, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0, 2, 189, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f1, 1, 191, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2, 1, 191, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f4, 1, 192, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6, 1, 193, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f7, 1, 194, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8, 1, 195, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa, 1, 196, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc, 1, 197, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe, 1, 198, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x200, 1, 199, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x202, 1, 200, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x204, 1, 201, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x206, 1, 202, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x208, 1, 203, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x20a, 1, 204, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x20c, 1, 205, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x20e, 1, 206, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x210, 1, 207, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x212, 1, 208, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x214, 1, 209, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216, 1, 210, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x218, 1, 211, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x21a, 1, 212, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x21c, 1, 213, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x21e, 1, 214, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x220, 1, 215, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x222, 1, 216, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x224, 1, 217, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x226, 1, 218, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x228, 1, 219, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x22a, 1, 220, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x22c, 1, 221, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x22e, 1, 222, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x230, 1, 223, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x232, 1, 224, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x345, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x34f, 0, 226, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x37a, 2, 226, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x386, 1, 228, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x388, 1, 229, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x389, 1, 230, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x38a, 1, 231, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x38c, 1, 232, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x38e, 1, 233, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x38f, 1, 234, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x390, 3, 235, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x391, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x392, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x393, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x394, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x395, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x396, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x397, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x398, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x399, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39a, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39b, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39c, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39d, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39e, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x39f, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a0, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a1, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a3, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a4, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a5, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a6, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a7, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a8, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3a9, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3aa, 1, 260, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3ab, 1, 261, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3b0, 3, 262, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3c2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3d0, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3d1, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3d2, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3d3, 1, 233, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3d4, 1, 261, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3d5, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3d6, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3d8, 1, 265, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3da, 1, 266, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3dc, 1, 267, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3de, 1, 268, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3e0, 1, 269, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3e2, 1, 270, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3e4, 1, 271, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3e6, 1, 272, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3e8, 1, 273, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3ea, 1, 274, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3ec, 1, 275, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3ee, 1, 276, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3f0, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3f1, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3f2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3f4, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3f5, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x400, 1, 277, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x401, 1, 278, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x402, 1, 279, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x403, 1, 280, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x404, 1, 281, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x405, 1, 282, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x406, 1, 283, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x407, 1, 284, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x408, 1, 285, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x409, 1, 286, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40a, 1, 287, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40b, 1, 288, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40c, 1, 289, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40d, 1, 290, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40e, 1, 291, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x40f, 1, 292, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x410, 1, 293, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x411, 1, 294, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x412, 1, 295, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x413, 1, 296, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x414, 1, 297, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x415, 1, 298, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x416, 1, 299, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x417, 1, 300, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x418, 1, 301, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x419, 1, 302, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41a, 1, 303, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41b, 1, 304, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41c, 1, 305, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41d, 1, 306, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41e, 1, 307, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x41f, 1, 308, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x420, 1, 309, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x421, 1, 310, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x422, 1, 311, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x423, 1, 312, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x424, 1, 313, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x425, 1, 314, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x426, 1, 315, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x427, 1, 316, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x428, 1, 317, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x429, 1, 318, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42a, 1, 319, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42b, 1, 320, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42c, 1, 321, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42d, 1, 322, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42e, 1, 323, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x42f, 1, 324, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x460, 1, 325, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x462, 1, 326, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x464, 1, 327, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x466, 1, 328, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x468, 1, 329, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x46a, 1, 330, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x46c, 1, 331, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x46e, 1, 332, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x470, 1, 333, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x472, 1, 334, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x474, 1, 335, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x476, 1, 336, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x478, 1, 337, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x47a, 1, 338, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x47c, 1, 339, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x47e, 1, 340, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x480, 1, 341, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x48a, 1, 342, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x48c, 1, 343, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x48e, 1, 344, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x490, 1, 345, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x492, 1, 346, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x494, 1, 347, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x496, 1, 348, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x498, 1, 349, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x49a, 1, 350, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x49c, 1, 351, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x49e, 1, 352, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a0, 1, 353, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a2, 1, 354, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a4, 1, 355, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a6, 1, 356, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4a8, 1, 357, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4aa, 1, 358, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ac, 1, 359, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ae, 1, 360, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b0, 1, 361, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b2, 1, 362, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b4, 1, 363, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b6, 1, 364, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4b8, 1, 365, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ba, 1, 366, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4bc, 1, 367, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4be, 1, 368, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c1, 1, 369, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c3, 1, 370, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c5, 1, 371, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c7, 1, 372, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4c9, 1, 373, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4cb, 1, 374, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4cd, 1, 375, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d0, 1, 376, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d2, 1, 377, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d4, 1, 378, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d6, 1, 379, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4d8, 1, 380, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4da, 1, 381, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4dc, 1, 382, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4de, 1, 383, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e0, 1, 384, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e2, 1, 385, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e4, 1, 386, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e6, 1, 387, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4e8, 1, 388, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ea, 1, 389, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ec, 1, 390, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4ee, 1, 391, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4f0, 1, 392, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4f2, 1, 393, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4f4, 1, 394, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x4f8, 1, 395, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x500, 1, 396, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x502, 1, 397, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x504, 1, 398, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x506, 1, 399, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x508, 1, 400, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x50a, 1, 401, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x50c, 1, 402, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x50e, 1, 403, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x531, 1, 404, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x532, 1, 405, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x533, 1, 406, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x534, 1, 407, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x535, 1, 408, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x536, 1, 409, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x537, 1, 410, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x538, 1, 411, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x539, 1, 412, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53a, 1, 413, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53b, 1, 414, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53c, 1, 415, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53d, 1, 416, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53e, 1, 417, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x53f, 1, 418, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x540, 1, 419, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x541, 1, 420, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x542, 1, 421, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x543, 1, 422, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x544, 1, 423, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x545, 1, 424, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x546, 1, 425, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x547, 1, 426, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x548, 1, 427, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x549, 1, 428, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54a, 1, 429, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54b, 1, 430, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54c, 1, 431, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54d, 1, 432, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54e, 1, 433, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x54f, 1, 434, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x550, 1, 435, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x551, 1, 436, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x552, 1, 437, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x553, 1, 438, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x554, 1, 439, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x555, 1, 440, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x556, 1, 441, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x587, 2, 442, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x6dd, 0, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x70f, 0, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1680, 1, 444, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x1806, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x180b, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x180c, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x180d, 0, 445, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x180e, 0, 445, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1e00, 1, 445, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e02, 1, 446, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e04, 1, 447, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e06, 1, 448, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e08, 1, 449, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e0a, 1, 450, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e0c, 1, 451, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e0e, 1, 452, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e10, 1, 453, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e12, 1, 454, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e14, 1, 455, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e16, 1, 456, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e18, 1, 457, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e1a, 1, 458, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e1c, 1, 459, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e1e, 1, 460, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e20, 1, 461, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e22, 1, 462, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e24, 1, 463, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e26, 1, 464, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e28, 1, 465, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e2a, 1, 466, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e2c, 1, 467, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e2e, 1, 468, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e30, 1, 469, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e32, 1, 470, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e34, 1, 471, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e36, 1, 472, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e38, 1, 473, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e3a, 1, 474, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e3c, 1, 475, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e3e, 1, 476, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e40, 1, 477, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e42, 1, 478, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e44, 1, 479, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e46, 1, 480, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e48, 1, 481, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e4a, 1, 482, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e4c, 1, 483, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e4e, 1, 484, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e50, 1, 485, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e52, 1, 486, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e54, 1, 487, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e56, 1, 488, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e58, 1, 489, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e5a, 1, 490, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e5c, 1, 491, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e5e, 1, 492, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e60, 1, 493, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e62, 1, 494, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e64, 1, 495, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e66, 1, 496, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e68, 1, 497, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e6a, 1, 498, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e6c, 1, 499, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e6e, 1, 500, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e70, 1, 501, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e72, 1, 502, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e74, 1, 503, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e76, 1, 504, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e78, 1, 505, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e7a, 1, 506, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e7c, 1, 507, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e7e, 1, 508, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e80, 1, 509, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e82, 1, 510, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e84, 1, 511, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e86, 1, 512, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e88, 1, 513, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e8a, 1, 514, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e8c, 1, 515, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e8e, 1, 516, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e90, 1, 517, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e92, 1, 518, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e94, 1, 519, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e96, 2, 520, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e97, 2, 522, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e98, 2, 524, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e99, 2, 526, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e9a, 2, 528, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1e9b, 1, 493, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea0, 1, 530, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea2, 1, 531, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea4, 1, 532, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea6, 1, 533, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ea8, 1, 534, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eaa, 1, 535, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eac, 1, 536, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eae, 1, 537, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eb0, 1, 538, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eb2, 1, 539, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eb4, 1, 540, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eb6, 1, 541, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eb8, 1, 542, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eba, 1, 543, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ebc, 1, 544, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ebe, 1, 545, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec0, 1, 546, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec2, 1, 547, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec4, 1, 548, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec6, 1, 549, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ec8, 1, 550, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eca, 1, 551, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ecc, 1, 552, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ece, 1, 553, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ed0, 1, 554, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ed2, 1, 555, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ed4, 1, 556, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ed6, 1, 557, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ed8, 1, 558, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eda, 1, 559, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1edc, 1, 560, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ede, 1, 561, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee0, 1, 562, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee2, 1, 563, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee4, 1, 564, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee6, 1, 565, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ee8, 1, 566, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eea, 1, 567, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eec, 1, 568, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1eee, 1, 569, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ef0, 1, 570, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ef2, 1, 571, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ef4, 1, 572, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ef6, 1, 573, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ef8, 1, 574, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f08, 1, 575, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f09, 1, 576, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0a, 1, 577, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0b, 1, 578, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0c, 1, 579, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0d, 1, 580, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0e, 1, 581, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f0f, 1, 582, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f18, 1, 583, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f19, 1, 584, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f1a, 1, 585, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f1b, 1, 586, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f1c, 1, 587, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f1d, 1, 588, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f28, 1, 589, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f29, 1, 590, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2a, 1, 591, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2b, 1, 592, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2c, 1, 593, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2d, 1, 594, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2e, 1, 595, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f2f, 1, 596, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f38, 1, 597, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f39, 1, 598, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3a, 1, 599, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3b, 1, 600, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3c, 1, 601, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3d, 1, 602, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3e, 1, 603, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f3f, 1, 604, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f48, 1, 605, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f49, 1, 606, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f4a, 1, 607, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f4b, 1, 608, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f4c, 1, 609, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f4d, 1, 610, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f50, 2, 611, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f52, 3, 613, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f54, 3, 616, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f56, 3, 619, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f59, 1, 622, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f5b, 1, 623, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f5d, 1, 624, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f5f, 1, 625, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f68, 1, 626, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f69, 1, 627, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6a, 1, 628, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6b, 1, 629, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6c, 1, 630, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6d, 1, 631, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6e, 1, 632, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f6f, 1, 633, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f80, 2, 634, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f81, 2, 636, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f82, 2, 638, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f83, 2, 640, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f84, 2, 642, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f85, 2, 644, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f86, 2, 646, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f87, 2, 648, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f88, 2, 634, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f89, 2, 636, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8a, 2, 638, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8b, 2, 640, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8c, 2, 642, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8d, 2, 644, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8e, 2, 646, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f8f, 2, 648, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f90, 2, 650, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f91, 2, 652, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f92, 2, 654, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f93, 2, 656, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f94, 2, 658, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f95, 2, 660, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f96, 2, 662, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f97, 2, 664, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f98, 2, 650, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f99, 2, 652, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9a, 2, 654, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9b, 2, 656, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9c, 2, 658, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9d, 2, 660, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9e, 2, 662, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1f9f, 2, 664, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa0, 2, 666, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa1, 2, 668, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa2, 2, 670, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa3, 2, 672, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa4, 2, 674, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa5, 2, 676, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa6, 2, 678, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa7, 2, 680, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa8, 2, 666, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fa9, 2, 668, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1faa, 2, 670, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fab, 2, 672, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fac, 2, 674, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fad, 2, 676, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fae, 2, 678, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1faf, 2, 680, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb2, 2, 682, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb3, 2, 684, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb4, 2, 686, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb6, 2, 688, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb7, 3, 690, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb8, 1, 693, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fb9, 1, 694, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fba, 1, 682, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fbb, 1, 695, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fbc, 2, 684, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fbe, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc2, 2, 696, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc3, 2, 698, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc4, 2, 700, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc6, 2, 702, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc7, 3, 704, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc8, 1, 707, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fc9, 1, 708, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fca, 1, 696, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fcb, 1, 709, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fcc, 2, 698, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd2, 3, 710, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd3, 3, 235, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd6, 2, 713, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd7, 3, 715, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd8, 1, 718, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fd9, 1, 719, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fda, 1, 720, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fdb, 1, 721, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe2, 3, 722, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe3, 3, 262, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe4, 2, 725, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe6, 2, 727, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe7, 3, 729, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe8, 1, 732, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fe9, 1, 733, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fea, 1, 734, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1feb, 1, 735, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1fec, 1, 736, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff2, 2, 737, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff3, 2, 739, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff4, 2, 234, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff6, 2, 741, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff7, 3, 743, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff8, 1, 746, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ff9, 1, 747, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ffa, 1, 737, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ffb, 1, 748, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1ffc, 2, 739, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2000, 1, 749, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2001, 1, 750, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2002, 1, 751, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2003, 1, 752, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2004, 1, 753, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2005, 1, 754, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2006, 1, 755, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2007, 1, 756, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2008, 1, 757, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2009, 1, 758, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x200b, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x200c, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x200d, 0, 759, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x200e, 0, 759, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x2028, 1, 759, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x202a, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x202b, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x202c, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x202d, 0, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x202f, 1, 760, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x205f, 1, 761, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x2060, 0, 762, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0x2061, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x2062, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x206a, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x206b, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x206c, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x206d, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x206e, 0, 762, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x20a8, 2, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2102, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2103, 2, 762, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2107, 1, 143, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2109, 2, 764, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x210b, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x210c, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x210d, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2110, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2111, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2112, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2115, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2116, 2, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2119, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x211a, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x211b, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x211c, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x211d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2120, 2, 766, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2121, 3, 768, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2122, 2, 771, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2124, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2126, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2128, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x212a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x212b, 1, 40, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x212c, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x212d, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2130, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2131, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2133, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x213e, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x213f, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2145, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x2160, 1, 773, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2161, 1, 774, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2162, 1, 775, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2163, 1, 776, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2164, 1, 777, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2165, 1, 778, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2166, 1, 779, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2167, 1, 780, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2168, 1, 781, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x2169, 1, 782, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216a, 1, 783, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216b, 1, 784, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216c, 1, 785, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216d, 1, 786, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216e, 1, 787, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x216f, 1, 788, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24b6, 1, 789, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24b7, 1, 790, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24b8, 1, 791, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24b9, 1, 792, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24ba, 1, 793, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24bb, 1, 794, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24bc, 1, 795, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24bd, 1, 796, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24be, 1, 797, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24bf, 1, 798, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c0, 1, 799, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c1, 1, 800, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c2, 1, 801, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c3, 1, 802, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c4, 1, 803, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c5, 1, 804, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c6, 1, 805, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c7, 1, 806, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c8, 1, 807, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24c9, 1, 808, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24ca, 1, 809, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24cb, 1, 810, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24cc, 1, 811, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24cd, 1, 812, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24ce, 1, 813, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x24cf, 1, 814, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x3000, 1, 815, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to SPACE */
+  {0x3371, 3, 816, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3373, 2, 819, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3375, 2, 821, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3380, 2, 817, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3381, 2, 823, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3382, 2, 825, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3383, 2, 827, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3384, 2, 829, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3385, 2, 831, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3386, 2, 833, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3387, 2, 835, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x338a, 2, 837, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x338b, 2, 839, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x338c, 2, 841, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3390, 2, 843, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3391, 3, 845, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3392, 3, 848, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3393, 3, 851, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x3394, 3, 854, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33a9, 2, 817, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33aa, 3, 857, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33ab, 3, 860, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33ac, 3, 863, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b4, 2, 866, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b5, 2, 868, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b6, 2, 870, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b7, 2, 872, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b8, 2, 874, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33b9, 2, 872, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33ba, 2, 876, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33bb, 2, 878, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33bc, 2, 880, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33bd, 2, 882, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33be, 2, 884, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33bf, 2, 882, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c0, 2, 886, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c1, 2, 888, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c3, 2, 890, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c6, 4, 892, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c7, 3, 896, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c8, 2, 899, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33c9, 2, 901, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33cb, 2, 816, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33cd, 2, 903, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33ce, 2, 905, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33d7, 2, 907, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33d9, 3, 909, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33da, 2, 912, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33dc, 2, 914, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x33dd, 2, 916, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0xfb00, 2, 918, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb01, 2, 920, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb02, 2, 922, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb03, 3, 919, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb04, 3, 924, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb05, 2, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb06, 2, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb13, 2, 927, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb14, 2, 929, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb15, 2, 931, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb16, 2, 933, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfb17, 2, 935, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfe00, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe01, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe02, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe03, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe04, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe05, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe06, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe07, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe08, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe09, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0a, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0b, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0c, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0d, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0e, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfe0f, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xfeff, 0, 937, WIND_PROFILE_NAME|WIND_PROFILE_SASL|WIND_PROFILE_LDAP}, /* B.1,rfc4518-map: Map to nothing */
+  {0xff21, 1, 937, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff22, 1, 938, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff23, 1, 939, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff24, 1, 940, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff25, 1, 941, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff26, 1, 942, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff27, 1, 943, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff28, 1, 944, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff29, 1, 945, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2a, 1, 946, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2b, 1, 947, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2c, 1, 948, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2d, 1, 949, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2e, 1, 950, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff2f, 1, 951, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff30, 1, 952, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff31, 1, 953, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff32, 1, 954, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff33, 1, 955, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff34, 1, 956, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff35, 1, 957, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff36, 1, 958, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff37, 1, 959, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff38, 1, 960, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff39, 1, 961, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xff3a, 1, 962, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0xfff9, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xfffa, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xfffc, 0, 963, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x10400, 1, 963, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10401, 1, 964, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10402, 1, 965, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10403, 1, 966, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10404, 1, 967, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10405, 1, 968, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10406, 1, 969, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10407, 1, 970, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10408, 1, 971, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10409, 1, 972, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040a, 1, 973, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040b, 1, 974, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040c, 1, 975, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040d, 1, 976, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040e, 1, 977, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1040f, 1, 978, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10410, 1, 979, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10411, 1, 980, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10412, 1, 981, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10413, 1, 982, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10414, 1, 983, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10415, 1, 984, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10416, 1, 985, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10417, 1, 986, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10418, 1, 987, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10419, 1, 988, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041a, 1, 989, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041b, 1, 990, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041c, 1, 991, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041d, 1, 992, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041e, 1, 993, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1041f, 1, 994, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10420, 1, 995, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10421, 1, 996, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10422, 1, 997, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10423, 1, 998, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10424, 1, 999, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x10425, 1, 1000, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Case map */
+  {0x1d173, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d174, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d175, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d176, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d177, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d178, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d179, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0x1d400, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d401, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d402, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d403, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d404, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d405, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d406, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d407, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d408, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d409, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40b, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40c, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40d, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40e, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d40f, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d410, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d411, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d412, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d413, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d414, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d415, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d416, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d417, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d418, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d419, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d434, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d435, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d436, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d437, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d438, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d439, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43a, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43b, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43c, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43d, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43e, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d43f, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d440, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d441, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d442, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d443, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d444, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d445, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d446, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d447, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d448, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d449, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d44a, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d44b, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d44c, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d44d, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d468, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d469, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46a, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d46f, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d470, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d471, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d472, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d473, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d474, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d475, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d476, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d477, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d478, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d479, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d47f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d480, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d481, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d49c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d49e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d49f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4a2, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4a5, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4a6, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4a9, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4aa, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4ab, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4ac, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4ae, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4af, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b0, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b1, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b2, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b3, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b4, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4b5, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d0, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d1, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d2, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d3, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d4, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d5, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d6, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d7, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d8, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4d9, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4da, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4db, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4dc, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4dd, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4de, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4df, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e0, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e1, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e2, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e3, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e4, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e5, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e6, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e7, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e8, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d4e9, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d504, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d505, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d507, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d508, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d509, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d50a, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d50d, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d50e, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d50f, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d510, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d511, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d512, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d513, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d514, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d516, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d517, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d518, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d519, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d51a, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d51b, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d51c, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d538, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d539, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d53b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d53c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d53d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d53e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d540, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d541, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d542, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d543, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d544, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d546, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d54f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d550, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d56c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d56d, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d56e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d56f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d570, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d571, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d572, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d573, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d574, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d575, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d576, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d577, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d578, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d579, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57a, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57b, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57c, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57e, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d57f, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d580, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d581, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d582, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d583, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d584, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d585, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a0, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a1, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a2, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a3, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a4, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a5, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a6, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a7, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a8, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5a9, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5aa, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ab, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ac, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ad, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ae, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5af, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b0, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b1, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b2, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b3, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b4, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b5, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b6, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b7, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b8, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5b9, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d4, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d5, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d6, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d7, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d8, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5d9, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5da, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5db, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5dc, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5dd, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5de, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5df, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e0, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e1, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e2, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e3, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e4, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e5, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e6, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e7, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e8, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5e9, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ea, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5eb, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ec, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d5ed, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d608, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d609, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60a, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60b, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60c, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60d, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60e, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d60f, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d610, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d611, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d612, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d613, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d614, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d615, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d616, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d617, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d618, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d619, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61a, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61b, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61c, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61d, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61e, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d61f, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d620, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d621, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d63c, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d63d, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d63e, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d63f, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d640, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d641, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d642, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d643, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d644, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d645, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d646, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d647, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d648, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d649, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64a, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64b, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64c, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64d, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64e, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d64f, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d650, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d651, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d652, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d653, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d654, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d655, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d670, 1, 6, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d671, 1, 7, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d672, 1, 8, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d673, 1, 9, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d674, 1, 10, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d675, 1, 11, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d676, 1, 12, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d677, 1, 13, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d678, 1, 14, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d679, 1, 15, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67a, 1, 16, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67b, 1, 17, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67c, 1, 18, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67d, 1, 19, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67e, 1, 20, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d67f, 1, 21, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d680, 1, 22, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d681, 1, 23, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d682, 1, 24, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d683, 1, 25, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d684, 1, 26, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d685, 1, 27, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d686, 1, 28, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d687, 1, 29, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d688, 1, 30, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d689, 1, 31, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6a8, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6a9, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6aa, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ab, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ac, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ad, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ae, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6af, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b0, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b1, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b2, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b3, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b4, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b5, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b6, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b7, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b8, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6b9, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ba, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6bb, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6bc, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6bd, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6be, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6bf, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6c0, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6d3, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e2, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e3, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e4, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e5, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e6, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e7, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e8, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6e9, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ea, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6eb, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ec, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ed, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ee, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6ef, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f0, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f1, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f2, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f3, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f4, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f5, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f6, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f7, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f8, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6f9, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d6fa, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d70d, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d71c, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d71d, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d71e, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d71f, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d720, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d721, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d722, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d723, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d724, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d725, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d726, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d727, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d728, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d729, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72a, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72b, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72c, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72d, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72e, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d72f, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d730, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d731, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d732, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d733, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d734, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d747, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d756, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d757, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d758, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d759, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75a, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75b, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75c, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75d, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75e, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d75f, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d760, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d761, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d762, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d763, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d764, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d765, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d766, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d767, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d768, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d769, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d76a, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d76b, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d76c, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d76d, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d76e, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d781, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d790, 1, 238, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d791, 1, 239, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d792, 1, 240, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d793, 1, 241, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d794, 1, 242, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d795, 1, 243, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d796, 1, 244, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d797, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d798, 1, 225, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d799, 1, 246, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79a, 1, 247, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79b, 1, 34, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79c, 1, 248, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79d, 1, 249, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79e, 1, 250, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d79f, 1, 251, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a0, 1, 252, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a1, 1, 245, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a2, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a3, 1, 254, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a4, 1, 255, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a5, 1, 256, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a6, 1, 257, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a7, 1, 258, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7a8, 1, 259, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0x1d7bb, 1, 253, WIND_PROFILE_NAME|WIND_PROFILE_LDAP}, /* B.2: Additional folding */
+  {0xe0001, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0020, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0021, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0022, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0023, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0024, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0025, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0026, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0027, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0028, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0029, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe002f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0030, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0031, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0032, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0033, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0034, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0035, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0036, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0037, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0038, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0039, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe003f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0040, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0041, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0042, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0043, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0044, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0045, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0046, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0047, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0048, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0049, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe004f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0050, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0051, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0052, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0053, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0054, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0055, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0056, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0057, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0058, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0059, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe005f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0060, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0061, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0062, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0063, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0064, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0065, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0066, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0067, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0068, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0069, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe006f, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0070, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0071, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0072, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0073, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0074, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0075, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0076, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0077, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0078, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe0079, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe007a, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe007b, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe007c, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe007d, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+  {0xe007e, 0, 1001, WIND_PROFILE_LDAP}, /* rfc4518-map: Map to nothing */
+
+};
+
+const size_t _wind_map_table_size = 1597;
+
+const uint32_t _wind_map_table_val[] = {
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0061,
+  0x0062,
+  0x0063,
+  0x0064,
+  0x0065,
+  0x0066,
+  0x0067,
+  0x0068,
+  0x0069,
+  0x006A,
+  0x006B,
+  0x006C,
+  0x006D,
+  0x006E,
+  0x006F,
+  0x0070,
+  0x0071,
+  0x0072,
+  0x0073,
+  0x0074,
+  0x0075,
+  0x0076,
+  0x0077,
+  0x0078,
+  0x0079,
+  0x007A,
+  0x0020,
+  0x0020,
+  0x03BC,
+  0x00E0,
+  0x00E1,
+  0x00E2,
+  0x00E3,
+  0x00E4,
+  0x00E5,
+  0x00E6,
+  0x00E7,
+  0x00E8,
+  0x00E9,
+  0x00EA,
+  0x00EB,
+  0x00EC,
+  0x00ED,
+  0x00EE,
+  0x00EF,
+  0x00F0,
+  0x00F1,
+  0x00F2,
+  0x00F3,
+  0x00F4,
+  0x00F5,
+  0x00F6,
+  0x00F8,
+  0x00F9,
+  0x00FA,
+  0x00FB,
+  0x00FC,
+  0x00FD,
+  0x00FE,
+  0x0073,
+  0x0073,
+  0x0101,
+  0x0103,
+  0x0105,
+  0x0107,
+  0x0109,
+  0x010B,
+  0x010D,
+  0x010F,
+  0x0111,
+  0x0113,
+  0x0115,
+  0x0117,
+  0x0119,
+  0x011B,
+  0x011D,
+  0x011F,
+  0x0121,
+  0x0123,
+  0x0125,
+  0x0127,
+  0x0129,
+  0x012B,
+  0x012D,
+  0x012F,
+  0x0069,
+  0x0307,
+  0x0133,
+  0x0135,
+  0x0137,
+  0x013A,
+  0x013C,
+  0x013E,
+  0x0140,
+  0x0142,
+  0x0144,
+  0x0146,
+  0x0148,
+  0x02BC,
+  0x006E,
+  0x014B,
+  0x014D,
+  0x014F,
+  0x0151,
+  0x0153,
+  0x0155,
+  0x0157,
+  0x0159,
+  0x015B,
+  0x015D,
+  0x015F,
+  0x0161,
+  0x0163,
+  0x0165,
+  0x0167,
+  0x0169,
+  0x016B,
+  0x016D,
+  0x016F,
+  0x0171,
+  0x0173,
+  0x0175,
+  0x0177,
+  0x00FF,
+  0x017A,
+  0x017C,
+  0x017E,
+  0x0253,
+  0x0183,
+  0x0185,
+  0x0254,
+  0x0188,
+  0x0256,
+  0x0257,
+  0x018C,
+  0x01DD,
+  0x0259,
+  0x025B,
+  0x0192,
+  0x0260,
+  0x0263,
+  0x0269,
+  0x0268,
+  0x0199,
+  0x026F,
+  0x0272,
+  0x0275,
+  0x01A1,
+  0x01A3,
+  0x01A5,
+  0x0280,
+  0x01A8,
+  0x0283,
+  0x01AD,
+  0x0288,
+  0x01B0,
+  0x028A,
+  0x028B,
+  0x01B4,
+  0x01B6,
+  0x0292,
+  0x01B9,
+  0x01BD,
+  0x01C6,
+  0x01C9,
+  0x01CC,
+  0x01CE,
+  0x01D0,
+  0x01D2,
+  0x01D4,
+  0x01D6,
+  0x01D8,
+  0x01DA,
+  0x01DC,
+  0x01DF,
+  0x01E1,
+  0x01E3,
+  0x01E5,
+  0x01E7,
+  0x01E9,
+  0x01EB,
+  0x01ED,
+  0x01EF,
+  0x006A,
+  0x030C,
+  0x01F3,
+  0x01F5,
+  0x0195,
+  0x01BF,
+  0x01F9,
+  0x01FB,
+  0x01FD,
+  0x01FF,
+  0x0201,
+  0x0203,
+  0x0205,
+  0x0207,
+  0x0209,
+  0x020B,
+  0x020D,
+  0x020F,
+  0x0211,
+  0x0213,
+  0x0215,
+  0x0217,
+  0x0219,
+  0x021B,
+  0x021D,
+  0x021F,
+  0x019E,
+  0x0223,
+  0x0225,
+  0x0227,
+  0x0229,
+  0x022B,
+  0x022D,
+  0x022F,
+  0x0231,
+  0x0233,
+  0x03B9,
+  0x0020,
+  0x03B9,
+  0x03AC,
+  0x03AD,
+  0x03AE,
+  0x03AF,
+  0x03CC,
+  0x03CD,
+  0x03CE,
+  0x03B9,
+  0x0308,
+  0x0301,
+  0x03B1,
+  0x03B2,
+  0x03B3,
+  0x03B4,
+  0x03B5,
+  0x03B6,
+  0x03B7,
+  0x03B8,
+  0x03BA,
+  0x03BB,
+  0x03BD,
+  0x03BE,
+  0x03BF,
+  0x03C0,
+  0x03C1,
+  0x03C3,
+  0x03C4,
+  0x03C5,
+  0x03C6,
+  0x03C7,
+  0x03C8,
+  0x03C9,
+  0x03CA,
+  0x03CB,
+  0x03C5,
+  0x0308,
+  0x0301,
+  0x03D9,
+  0x03DB,
+  0x03DD,
+  0x03DF,
+  0x03E1,
+  0x03E3,
+  0x03E5,
+  0x03E7,
+  0x03E9,
+  0x03EB,
+  0x03ED,
+  0x03EF,
+  0x0450,
+  0x0451,
+  0x0452,
+  0x0453,
+  0x0454,
+  0x0455,
+  0x0456,
+  0x0457,
+  0x0458,
+  0x0459,
+  0x045A,
+  0x045B,
+  0x045C,
+  0x045D,
+  0x045E,
+  0x045F,
+  0x0430,
+  0x0431,
+  0x0432,
+  0x0433,
+  0x0434,
+  0x0435,
+  0x0436,
+  0x0437,
+  0x0438,
+  0x0439,
+  0x043A,
+  0x043B,
+  0x043C,
+  0x043D,
+  0x043E,
+  0x043F,
+  0x0440,
+  0x0441,
+  0x0442,
+  0x0443,
+  0x0444,
+  0x0445,
+  0x0446,
+  0x0447,
+  0x0448,
+  0x0449,
+  0x044A,
+  0x044B,
+  0x044C,
+  0x044D,
+  0x044E,
+  0x044F,
+  0x0461,
+  0x0463,
+  0x0465,
+  0x0467,
+  0x0469,
+  0x046B,
+  0x046D,
+  0x046F,
+  0x0471,
+  0x0473,
+  0x0475,
+  0x0477,
+  0x0479,
+  0x047B,
+  0x047D,
+  0x047F,
+  0x0481,
+  0x048B,
+  0x048D,
+  0x048F,
+  0x0491,
+  0x0493,
+  0x0495,
+  0x0497,
+  0x0499,
+  0x049B,
+  0x049D,
+  0x049F,
+  0x04A1,
+  0x04A3,
+  0x04A5,
+  0x04A7,
+  0x04A9,
+  0x04AB,
+  0x04AD,
+  0x04AF,
+  0x04B1,
+  0x04B3,
+  0x04B5,
+  0x04B7,
+  0x04B9,
+  0x04BB,
+  0x04BD,
+  0x04BF,
+  0x04C2,
+  0x04C4,
+  0x04C6,
+  0x04C8,
+  0x04CA,
+  0x04CC,
+  0x04CE,
+  0x04D1,
+  0x04D3,
+  0x04D5,
+  0x04D7,
+  0x04D9,
+  0x04DB,
+  0x04DD,
+  0x04DF,
+  0x04E1,
+  0x04E3,
+  0x04E5,
+  0x04E7,
+  0x04E9,
+  0x04EB,
+  0x04ED,
+  0x04EF,
+  0x04F1,
+  0x04F3,
+  0x04F5,
+  0x04F9,
+  0x0501,
+  0x0503,
+  0x0505,
+  0x0507,
+  0x0509,
+  0x050B,
+  0x050D,
+  0x050F,
+  0x0561,
+  0x0562,
+  0x0563,
+  0x0564,
+  0x0565,
+  0x0566,
+  0x0567,
+  0x0568,
+  0x0569,
+  0x056A,
+  0x056B,
+  0x056C,
+  0x056D,
+  0x056E,
+  0x056F,
+  0x0570,
+  0x0571,
+  0x0572,
+  0x0573,
+  0x0574,
+  0x0575,
+  0x0576,
+  0x0577,
+  0x0578,
+  0x0579,
+  0x057A,
+  0x057B,
+  0x057C,
+  0x057D,
+  0x057E,
+  0x057F,
+  0x0580,
+  0x0581,
+  0x0582,
+  0x0583,
+  0x0584,
+  0x0585,
+  0x0586,
+  0x0565,
+  0x0582,
+  0x0020,
+  0x1E01,
+  0x1E03,
+  0x1E05,
+  0x1E07,
+  0x1E09,
+  0x1E0B,
+  0x1E0D,
+  0x1E0F,
+  0x1E11,
+  0x1E13,
+  0x1E15,
+  0x1E17,
+  0x1E19,
+  0x1E1B,
+  0x1E1D,
+  0x1E1F,
+  0x1E21,
+  0x1E23,
+  0x1E25,
+  0x1E27,
+  0x1E29,
+  0x1E2B,
+  0x1E2D,
+  0x1E2F,
+  0x1E31,
+  0x1E33,
+  0x1E35,
+  0x1E37,
+  0x1E39,
+  0x1E3B,
+  0x1E3D,
+  0x1E3F,
+  0x1E41,
+  0x1E43,
+  0x1E45,
+  0x1E47,
+  0x1E49,
+  0x1E4B,
+  0x1E4D,
+  0x1E4F,
+  0x1E51,
+  0x1E53,
+  0x1E55,
+  0x1E57,
+  0x1E59,
+  0x1E5B,
+  0x1E5D,
+  0x1E5F,
+  0x1E61,
+  0x1E63,
+  0x1E65,
+  0x1E67,
+  0x1E69,
+  0x1E6B,
+  0x1E6D,
+  0x1E6F,
+  0x1E71,
+  0x1E73,
+  0x1E75,
+  0x1E77,
+  0x1E79,
+  0x1E7B,
+  0x1E7D,
+  0x1E7F,
+  0x1E81,
+  0x1E83,
+  0x1E85,
+  0x1E87,
+  0x1E89,
+  0x1E8B,
+  0x1E8D,
+  0x1E8F,
+  0x1E91,
+  0x1E93,
+  0x1E95,
+  0x0068,
+  0x0331,
+  0x0074,
+  0x0308,
+  0x0077,
+  0x030A,
+  0x0079,
+  0x030A,
+  0x0061,
+  0x02BE,
+  0x1EA1,
+  0x1EA3,
+  0x1EA5,
+  0x1EA7,
+  0x1EA9,
+  0x1EAB,
+  0x1EAD,
+  0x1EAF,
+  0x1EB1,
+  0x1EB3,
+  0x1EB5,
+  0x1EB7,
+  0x1EB9,
+  0x1EBB,
+  0x1EBD,
+  0x1EBF,
+  0x1EC1,
+  0x1EC3,
+  0x1EC5,
+  0x1EC7,
+  0x1EC9,
+  0x1ECB,
+  0x1ECD,
+  0x1ECF,
+  0x1ED1,
+  0x1ED3,
+  0x1ED5,
+  0x1ED7,
+  0x1ED9,
+  0x1EDB,
+  0x1EDD,
+  0x1EDF,
+  0x1EE1,
+  0x1EE3,
+  0x1EE5,
+  0x1EE7,
+  0x1EE9,
+  0x1EEB,
+  0x1EED,
+  0x1EEF,
+  0x1EF1,
+  0x1EF3,
+  0x1EF5,
+  0x1EF7,
+  0x1EF9,
+  0x1F00,
+  0x1F01,
+  0x1F02,
+  0x1F03,
+  0x1F04,
+  0x1F05,
+  0x1F06,
+  0x1F07,
+  0x1F10,
+  0x1F11,
+  0x1F12,
+  0x1F13,
+  0x1F14,
+  0x1F15,
+  0x1F20,
+  0x1F21,
+  0x1F22,
+  0x1F23,
+  0x1F24,
+  0x1F25,
+  0x1F26,
+  0x1F27,
+  0x1F30,
+  0x1F31,
+  0x1F32,
+  0x1F33,
+  0x1F34,
+  0x1F35,
+  0x1F36,
+  0x1F37,
+  0x1F40,
+  0x1F41,
+  0x1F42,
+  0x1F43,
+  0x1F44,
+  0x1F45,
+  0x03C5,
+  0x0313,
+  0x03C5,
+  0x0313,
+  0x0300,
+  0x03C5,
+  0x0313,
+  0x0301,
+  0x03C5,
+  0x0313,
+  0x0342,
+  0x1F51,
+  0x1F53,
+  0x1F55,
+  0x1F57,
+  0x1F60,
+  0x1F61,
+  0x1F62,
+  0x1F63,
+  0x1F64,
+  0x1F65,
+  0x1F66,
+  0x1F67,
+  0x1F00,
+  0x03B9,
+  0x1F01,
+  0x03B9,
+  0x1F02,
+  0x03B9,
+  0x1F03,
+  0x03B9,
+  0x1F04,
+  0x03B9,
+  0x1F05,
+  0x03B9,
+  0x1F06,
+  0x03B9,
+  0x1F07,
+  0x03B9,
+  0x1F20,
+  0x03B9,
+  0x1F21,
+  0x03B9,
+  0x1F22,
+  0x03B9,
+  0x1F23,
+  0x03B9,
+  0x1F24,
+  0x03B9,
+  0x1F25,
+  0x03B9,
+  0x1F26,
+  0x03B9,
+  0x1F27,
+  0x03B9,
+  0x1F60,
+  0x03B9,
+  0x1F61,
+  0x03B9,
+  0x1F62,
+  0x03B9,
+  0x1F63,
+  0x03B9,
+  0x1F64,
+  0x03B9,
+  0x1F65,
+  0x03B9,
+  0x1F66,
+  0x03B9,
+  0x1F67,
+  0x03B9,
+  0x1F70,
+  0x03B9,
+  0x03B1,
+  0x03B9,
+  0x03AC,
+  0x03B9,
+  0x03B1,
+  0x0342,
+  0x03B1,
+  0x0342,
+  0x03B9,
+  0x1FB0,
+  0x1FB1,
+  0x1F71,
+  0x1F74,
+  0x03B9,
+  0x03B7,
+  0x03B9,
+  0x03AE,
+  0x03B9,
+  0x03B7,
+  0x0342,
+  0x03B7,
+  0x0342,
+  0x03B9,
+  0x1F72,
+  0x1F73,
+  0x1F75,
+  0x03B9,
+  0x0308,
+  0x0300,
+  0x03B9,
+  0x0342,
+  0x03B9,
+  0x0308,
+  0x0342,
+  0x1FD0,
+  0x1FD1,
+  0x1F76,
+  0x1F77,
+  0x03C5,
+  0x0308,
+  0x0300,
+  0x03C1,
+  0x0313,
+  0x03C5,
+  0x0342,
+  0x03C5,
+  0x0308,
+  0x0342,
+  0x1FE0,
+  0x1FE1,
+  0x1F7A,
+  0x1F7B,
+  0x1FE5,
+  0x1F7C,
+  0x03B9,
+  0x03C9,
+  0x03B9,
+  0x03C9,
+  0x0342,
+  0x03C9,
+  0x0342,
+  0x03B9,
+  0x1F78,
+  0x1F79,
+  0x1F7D,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x0020,
+  0x00B0,
+  0x0063,
+  0x00B0,
+  0x0066,
+  0x0073,
+  0x006D,
+  0x0074,
+  0x0065,
+  0x006C,
+  0x0074,
+  0x006D,
+  0x2170,
+  0x2171,
+  0x2172,
+  0x2173,
+  0x2174,
+  0x2175,
+  0x2176,
+  0x2177,
+  0x2178,
+  0x2179,
+  0x217A,
+  0x217B,
+  0x217C,
+  0x217D,
+  0x217E,
+  0x217F,
+  0x24D0,
+  0x24D1,
+  0x24D2,
+  0x24D3,
+  0x24D4,
+  0x24D5,
+  0x24D6,
+  0x24D7,
+  0x24D8,
+  0x24D9,
+  0x24DA,
+  0x24DB,
+  0x24DC,
+  0x24DD,
+  0x24DE,
+  0x24DF,
+  0x24E0,
+  0x24E1,
+  0x24E2,
+  0x24E3,
+  0x24E4,
+  0x24E5,
+  0x24E6,
+  0x24E7,
+  0x24E8,
+  0x24E9,
+  0x0020,
+  0x0068,
+  0x0070,
+  0x0061,
+  0x0061,
+  0x0075,
+  0x006F,
+  0x0076,
+  0x006E,
+  0x0061,
+  0x03BC,
+  0x0061,
+  0x006D,
+  0x0061,
+  0x006B,
+  0x0061,
+  0x006B,
+  0x0062,
+  0x006D,
+  0x0062,
+  0x0067,
+  0x0062,
+  0x0070,
+  0x0066,
+  0x006E,
+  0x0066,
+  0x03BC,
+  0x0066,
+  0x0068,
+  0x007A,
+  0x006B,
+  0x0068,
+  0x007A,
+  0x006D,
+  0x0068,
+  0x007A,
+  0x0067,
+  0x0068,
+  0x007A,
+  0x0074,
+  0x0068,
+  0x007A,
+  0x006B,
+  0x0070,
+  0x0061,
+  0x006D,
+  0x0070,
+  0x0061,
+  0x0067,
+  0x0070,
+  0x0061,
+  0x0070,
+  0x0076,
+  0x006E,
+  0x0076,
+  0x03BC,
+  0x0076,
+  0x006D,
+  0x0076,
+  0x006B,
+  0x0076,
+  0x0070,
+  0x0077,
+  0x006E,
+  0x0077,
+  0x03BC,
+  0x0077,
+  0x006D,
+  0x0077,
+  0x006B,
+  0x0077,
+  0x006B,
+  0x03C9,
+  0x006D,
+  0x03C9,
+  0x0062,
+  0x0071,
+  0x0063,
+  0x2215,
+  0x006B,
+  0x0067,
+  0x0063,
+  0x006F,
+  0x002E,
+  0x0064,
+  0x0062,
+  0x0067,
+  0x0079,
+  0x006B,
+  0x006B,
+  0x006B,
+  0x006D,
+  0x0070,
+  0x0068,
+  0x0070,
+  0x0070,
+  0x006D,
+  0x0070,
+  0x0072,
+  0x0073,
+  0x0076,
+  0x0077,
+  0x0062,
+  0x0066,
+  0x0066,
+  0x0066,
+  0x0069,
+  0x0066,
+  0x006C,
+  0x0066,
+  0x0066,
+  0x006C,
+  0x0574,
+  0x0576,
+  0x0574,
+  0x0565,
+  0x0574,
+  0x056B,
+  0x057E,
+  0x0576,
+  0x0574,
+  0x056D,
+  0xFF41,
+  0xFF42,
+  0xFF43,
+  0xFF44,
+  0xFF45,
+  0xFF46,
+  0xFF47,
+  0xFF48,
+  0xFF49,
+  0xFF4A,
+  0xFF4B,
+  0xFF4C,
+  0xFF4D,
+  0xFF4E,
+  0xFF4F,
+  0xFF50,
+  0xFF51,
+  0xFF52,
+  0xFF53,
+  0xFF54,
+  0xFF55,
+  0xFF56,
+  0xFF57,
+  0xFF58,
+  0xFF59,
+  0xFF5A,
+  0x10428,
+  0x10429,
+  0x1042A,
+  0x1042B,
+  0x1042C,
+  0x1042D,
+  0x1042E,
+  0x1042F,
+  0x10430,
+  0x10431,
+  0x10432,
+  0x10433,
+  0x10434,
+  0x10435,
+  0x10436,
+  0x10437,
+  0x10438,
+  0x10439,
+  0x1043A,
+  0x1043B,
+  0x1043C,
+  0x1043D,
+  0x1043E,
+  0x1043F,
+  0x10440,
+  0x10441,
+  0x10442,
+  0x10443,
+  0x10444,
+  0x10445,
+  0x10446,
+  0x10447,
+  0x10448,
+  0x10449,
+  0x1044A,
+  0x1044B,
+  0x1044C,
+  0x1044D,
+};
+
diff --git a/source/heimdal/lib/wind/map_table.h b/source/heimdal/lib/wind/map_table.h
new file mode 100644 (file)
index 0000000..4b45654
--- /dev/null
@@ -0,0 +1,22 @@
+/* map_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.353625 */
+
+#ifndef MAP_TABLE_H
+#define MAP_TABLE_H 1
+
+#include "windlocl.h"
+
+struct translation {
+  uint32_t key;
+  unsigned short val_len;
+  unsigned short val_offset;
+  wind_profile_flags flags;
+};
+
+extern const struct translation _wind_map_table[];
+
+extern const size_t _wind_map_table_size;
+
+extern const uint32_t _wind_map_table_val[];
+
+#endif /* MAP_TABLE_H */
diff --git a/source/heimdal/lib/wind/normalize.c b/source/heimdal/lib/wind/normalize.c
new file mode 100644 (file)
index 0000000..d1b4405
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "normalize_table.h"
+
+RCSID("$Id: normalize.c 22581 2008-02-11 20:42:25Z lha $");
+
+static int
+translation_cmp(const void *key, const void *data)
+{
+    const struct translation *t1 = (const struct translation *)key;
+    const struct translation *t2 = (const struct translation *)data;
+
+    return t1->key - t2->key;
+}
+
+enum { s_base  = 0xAC00};
+enum { s_count = 11172};
+enum { l_base  = 0x1100};
+enum { l_count = 19};
+enum { v_base  = 0x1161};
+enum { v_count = 21};
+enum { t_base  = 0x11A7};
+enum { t_count = 28};
+enum { n_count = v_count * t_count};
+
+static int
+hangul_decomp(const uint32_t *in, size_t in_len,
+             uint32_t *out, size_t *out_len)
+{
+    uint32_t u = *in;
+    unsigned s_index;
+    unsigned l, v, t;
+    unsigned o;
+
+    if (u < s_base || u >= s_base + s_count)
+       return 0;
+    s_index = u - s_base;
+    l = l_base + s_index / n_count;
+    v = v_base + (s_index % n_count) / t_count;
+    t = t_base + s_index % t_count;
+    o = 2;
+    if (t != t_base)
+       ++o;
+    if (*out_len < o)
+       return WIND_ERR_OVERRUN;
+    out[0] = l;
+    out[1] = v;
+    if (t != t_base)
+       out[2] = t;
+    *out_len = o;
+    return 1;
+}
+
+static uint32_t
+hangul_composition(const uint32_t *in, size_t in_len)
+{
+    if (in_len < 2)
+       return 0;
+    if (in[0] >= l_base && in[0] < l_base + l_count) {
+       unsigned l_index = in[0] - l_base;
+       unsigned v_index;
+
+       if (in[1] < v_base || in[1] >= v_base + v_count)
+           return 0;
+       v_index = in[1] - v_base;
+       return (l_index * v_count + v_index) * t_count + s_base;
+    } else if (in[0] >= s_base && in[0] < s_base + s_count) {
+       unsigned s_index = in[0] - s_base;
+       unsigned t_index;
+
+       if (s_index % t_count != 0)
+           return 0;
+       if (in[1] < t_base || in[1] >= t_base + t_count)
+           return 0;
+       t_index = in[1] - t_base;
+       return in[0] + t_index;
+    }
+    return 0;
+}
+
+static int
+compat_decomp(const uint32_t *in, size_t in_len,
+             uint32_t *out, size_t *out_len)
+{
+    unsigned i;
+    unsigned o = 0;
+
+    for (i = 0; i < in_len; ++i) {
+       struct translation ts = {in[i]};
+       size_t sub_len = *out_len - o;
+       int ret;
+       
+       ret = hangul_decomp(in + i, in_len - i,
+                           out + o, &sub_len);
+       if (ret) {
+           if (ret == WIND_ERR_OVERRUN)
+               return ret;
+           o += sub_len;
+       } else {
+           void *s = bsearch(&ts,
+                             _wind_normalize_table,
+                             _wind_normalize_table_size,
+                             sizeof(_wind_normalize_table[0]),
+                             translation_cmp);
+           if (s != NULL) {
+               const struct translation *t = (const struct translation *)s;
+
+               ret = compat_decomp(_wind_normalize_val_table + t->val_offset,
+                                   t->val_len,
+                                   out + o, &sub_len);
+               if (ret)
+                   return ret;
+               o += sub_len;
+           } else {
+               if (o >= *out_len)
+                   return WIND_ERR_OVERRUN;
+               out[o++] = in[i];
+
+           }
+       }
+    }
+    *out_len = o;
+    return 0;
+}
+
+static int
+cc_cmp(const void *a, const void *b)
+{
+    const uint32_t *ua = (const uint32_t *)a;
+    const uint32_t *ub = (const uint32_t *)b;
+
+    return _wind_combining_class(*ua) - _wind_combining_class(*ub);
+}
+
+static void
+canonical_reorder(uint32_t *tmp, size_t tmp_len)
+{
+    unsigned i;
+
+    for (i = 0; i < tmp_len; ++i) {
+       int cc = _wind_combining_class(tmp[i]);
+       if (cc) {
+           size_t j;
+           for (j = i + 1;
+                j < tmp_len && _wind_combining_class(tmp[j]);
+                ++j)
+               ;
+           qsort(&tmp[i], j - i, sizeof(unsigned),
+                 cc_cmp);
+           i = j;
+       }
+    }
+}
+
+static uint32_t
+find_composition(const uint32_t *in, unsigned in_len)
+{
+    unsigned short canon_index = 0;
+    uint32_t cur;
+    unsigned n = 0;
+
+    cur = hangul_composition(in, in_len);
+    if (cur)
+       return cur;
+
+    do {
+       const struct canon_node *c = &_wind_canon_table[canon_index];
+       unsigned i;
+
+       if (n % 5 == 0) {
+           cur = *in++;
+           if (in_len-- == 0)
+               return c->val;
+       }
+
+       i = cur >> 16;
+       if (i < c->next_start || i >= c->next_end)
+           canon_index = 0;
+       else
+           canon_index =
+               _wind_canon_next_table[c->next_offset + i - c->next_start];
+       if (canon_index != 0) {
+           cur = (cur << 4) & 0xFFFFF;
+           ++n;
+       }
+    } while (canon_index != 0);
+    return 0;
+}
+
+static int
+combine(const uint32_t *in, size_t in_len,
+       uint32_t *out, size_t *out_len)
+{
+    unsigned i;
+    int ostarter;
+    unsigned o = 0;
+    int old_cc;
+    int cc;
+
+    for (i = 0; i < in_len;) {
+       while (i < in_len && (cc = _wind_combining_class(in[i])) != 0) {
+           out[o++] = in[i++];
+       }
+       if (i < in_len) {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+           ostarter = o;
+           out[o++] = in[i++];
+           old_cc   = -1;
+
+           while (i < in_len) {
+               uint32_t comb;
+               uint32_t v[2];
+
+               v[0] = out[ostarter];
+               v[1] = in[i];
+
+               cc = _wind_combining_class(in[i]);
+               if (old_cc != cc && (comb = find_composition(v, 2))) {
+                   out[ostarter] = comb;
+               } else if (cc == 0) {
+                   break;
+               } else {
+                   if (o >= *out_len)
+                       return WIND_ERR_OVERRUN;
+                   out[o++] = in[i];
+                   old_cc   = cc;
+               }
+               ++i;
+           }
+       }
+    }
+    *out_len = o;
+    return 0;
+}
+
+int
+_wind_stringprep_normalize(const uint32_t *in, size_t in_len,
+                          uint32_t *out, size_t *out_len)
+{
+    size_t tmp_len;
+    uint32_t *tmp;
+    int ret;
+
+    tmp_len = in_len * 4;
+    if (tmp_len < MAX_LENGTH_CANON)
+       tmp_len = MAX_LENGTH_CANON;
+    tmp = malloc(tmp_len * sizeof(uint32_t));
+    if (tmp == NULL)
+       return ENOMEM;
+
+    ret = compat_decomp(in, in_len, tmp, &tmp_len);
+    if (ret) {
+       free(tmp);
+       return ret;
+    }
+    canonical_reorder(tmp, tmp_len);
+    ret = combine(tmp, tmp_len, out, out_len);
+    free(tmp);
+    return ret;
+}
diff --git a/source/heimdal/lib/wind/normalize_table.c b/source/heimdal/lib/wind/normalize_table.c
new file mode 100644 (file)
index 0000000..c889319
--- /dev/null
@@ -0,0 +1,22976 @@
+/* normalize_table.c */
+/* Automatically generated at 2008-03-18T11:38:08.923861 */
+
+
+#include "normalize_table.h"
+
+const struct translation _wind_normalize_table[] = {
+  {0xa0, 1, 0}, /* NO-BREAK SPACE */
+  {0xa8, 2, 1}, /* DIAERESIS */
+  {0xaa, 1, 3}, /* FEMININE ORDINAL INDICATOR */
+  {0xaf, 2, 4}, /* MACRON */
+  {0xb2, 1, 6}, /* SUPERSCRIPT TWO */
+  {0xb3, 1, 7}, /* SUPERSCRIPT THREE */
+  {0xb4, 2, 8}, /* ACUTE ACCENT */
+  {0xb5, 1, 10}, /* MICRO SIGN */
+  {0xb8, 2, 11}, /* CEDILLA */
+  {0xb9, 1, 13}, /* SUPERSCRIPT ONE */
+  {0xba, 1, 14}, /* MASCULINE ORDINAL INDICATOR */
+  {0xbc, 3, 15}, /* VULGAR FRACTION ONE QUARTER */
+  {0xbd, 3, 18}, /* VULGAR FRACTION ONE HALF */
+  {0xbe, 3, 21}, /* VULGAR FRACTION THREE QUARTERS */
+  {0xc0, 2, 24}, /* LATIN CAPITAL LETTER A WITH GRAVE */
+  {0xc1, 2, 26}, /* LATIN CAPITAL LETTER A WITH ACUTE */
+  {0xc2, 2, 28}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+  {0xc3, 2, 30}, /* LATIN CAPITAL LETTER A WITH TILDE */
+  {0xc4, 2, 32}, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+  {0xc5, 2, 34}, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+  {0xc7, 2, 36}, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+  {0xc8, 2, 38}, /* LATIN CAPITAL LETTER E WITH GRAVE */
+  {0xc9, 2, 40}, /* LATIN CAPITAL LETTER E WITH ACUTE */
+  {0xca, 2, 42}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+  {0xcb, 2, 44}, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+  {0xcc, 2, 46}, /* LATIN CAPITAL LETTER I WITH GRAVE */
+  {0xcd, 2, 48}, /* LATIN CAPITAL LETTER I WITH ACUTE */
+  {0xce, 2, 50}, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+  {0xcf, 2, 52}, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+  {0xd1, 2, 54}, /* LATIN CAPITAL LETTER N WITH TILDE */
+  {0xd2, 2, 56}, /* LATIN CAPITAL LETTER O WITH GRAVE */
+  {0xd3, 2, 58}, /* LATIN CAPITAL LETTER O WITH ACUTE */
+  {0xd4, 2, 60}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
+  {0xd5, 2, 62}, /* LATIN CAPITAL LETTER O WITH TILDE */
+  {0xd6, 2, 64}, /* LATIN CAPITAL LETTER O WITH DIAERESIS */
+  {0xd9, 2, 66}, /* LATIN CAPITAL LETTER U WITH GRAVE */
+  {0xda, 2, 68}, /* LATIN CAPITAL LETTER U WITH ACUTE */
+  {0xdb, 2, 70}, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
+  {0xdc, 2, 72}, /* LATIN CAPITAL LETTER U WITH DIAERESIS */
+  {0xdd, 2, 74}, /* LATIN CAPITAL LETTER Y WITH ACUTE */
+  {0xe0, 2, 76}, /* LATIN SMALL LETTER A WITH GRAVE */
+  {0xe1, 2, 78}, /* LATIN SMALL LETTER A WITH ACUTE */
+  {0xe2, 2, 80}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */
+  {0xe3, 2, 82}, /* LATIN SMALL LETTER A WITH TILDE */
+  {0xe4, 2, 84}, /* LATIN SMALL LETTER A WITH DIAERESIS */
+  {0xe5, 2, 86}, /* LATIN SMALL LETTER A WITH RING ABOVE */
+  {0xe7, 2, 88}, /* LATIN SMALL LETTER C WITH CEDILLA */
+  {0xe8, 2, 90}, /* LATIN SMALL LETTER E WITH GRAVE */
+  {0xe9, 2, 92}, /* LATIN SMALL LETTER E WITH ACUTE */
+  {0xea, 2, 94}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */
+  {0xeb, 2, 96}, /* LATIN SMALL LETTER E WITH DIAERESIS */
+  {0xec, 2, 98}, /* LATIN SMALL LETTER I WITH GRAVE */
+  {0xed, 2, 100}, /* LATIN SMALL LETTER I WITH ACUTE */
+  {0xee, 2, 102}, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */
+  {0xef, 2, 104}, /* LATIN SMALL LETTER I WITH DIAERESIS */
+  {0xf1, 2, 106}, /* LATIN SMALL LETTER N WITH TILDE */
+  {0xf2, 2, 108}, /* LATIN SMALL LETTER O WITH GRAVE */
+  {0xf3, 2, 110}, /* LATIN SMALL LETTER O WITH ACUTE */
+  {0xf4, 2, 112}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */
+  {0xf5, 2, 114}, /* LATIN SMALL LETTER O WITH TILDE */
+  {0xf6, 2, 116}, /* LATIN SMALL LETTER O WITH DIAERESIS */
+  {0xf9, 2, 118}, /* LATIN SMALL LETTER U WITH GRAVE */
+  {0xfa, 2, 120}, /* LATIN SMALL LETTER U WITH ACUTE */
+  {0xfb, 2, 122}, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */
+  {0xfc, 2, 124}, /* LATIN SMALL LETTER U WITH DIAERESIS */
+  {0xfd, 2, 126}, /* LATIN SMALL LETTER Y WITH ACUTE */
+  {0xff, 2, 128}, /* LATIN SMALL LETTER Y WITH DIAERESIS */
+  {0x100, 2, 130}, /* LATIN CAPITAL LETTER A WITH MACRON */
+  {0x101, 2, 132}, /* LATIN SMALL LETTER A WITH MACRON */
+  {0x102, 2, 134}, /* LATIN CAPITAL LETTER A WITH BREVE */
+  {0x103, 2, 136}, /* LATIN SMALL LETTER A WITH BREVE */
+  {0x104, 2, 138}, /* LATIN CAPITAL LETTER A WITH OGONEK */
+  {0x105, 2, 140}, /* LATIN SMALL LETTER A WITH OGONEK */
+  {0x106, 2, 142}, /* LATIN CAPITAL LETTER C WITH ACUTE */
+  {0x107, 2, 144}, /* LATIN SMALL LETTER C WITH ACUTE */
+  {0x108, 2, 146}, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+  {0x109, 2, 148}, /* LATIN SMALL LETTER C WITH CIRCUMFLEX */
+  {0x10a, 2, 150}, /* LATIN CAPITAL LETTER C WITH DOT ABOVE */
+  {0x10b, 2, 152}, /* LATIN SMALL LETTER C WITH DOT ABOVE */
+  {0x10c, 2, 154}, /* LATIN CAPITAL LETTER C WITH CARON */
+  {0x10d, 2, 156}, /* LATIN SMALL LETTER C WITH CARON */
+  {0x10e, 2, 158}, /* LATIN CAPITAL LETTER D WITH CARON */
+  {0x10f, 2, 160}, /* LATIN SMALL LETTER D WITH CARON */
+  {0x112, 2, 162}, /* LATIN CAPITAL LETTER E WITH MACRON */
+  {0x113, 2, 164}, /* LATIN SMALL LETTER E WITH MACRON */
+  {0x114, 2, 166}, /* LATIN CAPITAL LETTER E WITH BREVE */
+  {0x115, 2, 168}, /* LATIN SMALL LETTER E WITH BREVE */
+  {0x116, 2, 170}, /* LATIN CAPITAL LETTER E WITH DOT ABOVE */
+  {0x117, 2, 172}, /* LATIN SMALL LETTER E WITH DOT ABOVE */
+  {0x118, 2, 174}, /* LATIN CAPITAL LETTER E WITH OGONEK */
+  {0x119, 2, 176}, /* LATIN SMALL LETTER E WITH OGONEK */
+  {0x11a, 2, 178}, /* LATIN CAPITAL LETTER E WITH CARON */
+  {0x11b, 2, 180}, /* LATIN SMALL LETTER E WITH CARON */
+  {0x11c, 2, 182}, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+  {0x11d, 2, 184}, /* LATIN SMALL LETTER G WITH CIRCUMFLEX */
+  {0x11e, 2, 186}, /* LATIN CAPITAL LETTER G WITH BREVE */
+  {0x11f, 2, 188}, /* LATIN SMALL LETTER G WITH BREVE */
+  {0x120, 2, 190}, /* LATIN CAPITAL LETTER G WITH DOT ABOVE */
+  {0x121, 2, 192}, /* LATIN SMALL LETTER G WITH DOT ABOVE */
+  {0x122, 2, 194}, /* LATIN CAPITAL LETTER G WITH CEDILLA */
+  {0x123, 2, 196}, /* LATIN SMALL LETTER G WITH CEDILLA */
+  {0x124, 2, 198}, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+  {0x125, 2, 200}, /* LATIN SMALL LETTER H WITH CIRCUMFLEX */
+  {0x128, 2, 202}, /* LATIN CAPITAL LETTER I WITH TILDE */
+  {0x129, 2, 204}, /* LATIN SMALL LETTER I WITH TILDE */
+  {0x12a, 2, 206}, /* LATIN CAPITAL LETTER I WITH MACRON */
+  {0x12b, 2, 208}, /* LATIN SMALL LETTER I WITH MACRON */
+  {0x12c, 2, 210}, /* LATIN CAPITAL LETTER I WITH BREVE */
+  {0x12d, 2, 212}, /* LATIN SMALL LETTER I WITH BREVE */
+  {0x12e, 2, 214}, /* LATIN CAPITAL LETTER I WITH OGONEK */
+  {0x12f, 2, 216}, /* LATIN SMALL LETTER I WITH OGONEK */
+  {0x130, 2, 218}, /* LATIN CAPITAL LETTER I WITH DOT ABOVE */
+  {0x132, 2, 220}, /* LATIN CAPITAL LIGATURE IJ */
+  {0x133, 2, 222}, /* LATIN SMALL LIGATURE IJ */
+  {0x134, 2, 224}, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+  {0x135, 2, 226}, /* LATIN SMALL LETTER J WITH CIRCUMFLEX */
+  {0x136, 2, 228}, /* LATIN CAPITAL LETTER K WITH CEDILLA */
+  {0x137, 2, 230}, /* LATIN SMALL LETTER K WITH CEDILLA */
+  {0x139, 2, 232}, /* LATIN CAPITAL LETTER L WITH ACUTE */
+  {0x13a, 2, 234}, /* LATIN SMALL LETTER L WITH ACUTE */
+  {0x13b, 2, 236}, /* LATIN CAPITAL LETTER L WITH CEDILLA */
+  {0x13c, 2, 238}, /* LATIN SMALL LETTER L WITH CEDILLA */
+  {0x13d, 2, 240}, /* LATIN CAPITAL LETTER L WITH CARON */
+  {0x13e, 2, 242}, /* LATIN SMALL LETTER L WITH CARON */
+  {0x13f, 2, 244}, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT */
+  {0x140, 2, 246}, /* LATIN SMALL LETTER L WITH MIDDLE DOT */
+  {0x143, 2, 248}, /* LATIN CAPITAL LETTER N WITH ACUTE */
+  {0x144, 2, 250}, /* LATIN SMALL LETTER N WITH ACUTE */
+  {0x145, 2, 252}, /* LATIN CAPITAL LETTER N WITH CEDILLA */
+  {0x146, 2, 254}, /* LATIN SMALL LETTER N WITH CEDILLA */
+  {0x147, 2, 256}, /* LATIN CAPITAL LETTER N WITH CARON */
+  {0x148, 2, 258}, /* LATIN SMALL LETTER N WITH CARON */
+  {0x149, 2, 260}, /* LATIN SMALL LETTER N PRECEDED BY APOSTROPHE */
+  {0x14c, 2, 262}, /* LATIN CAPITAL LETTER O WITH MACRON */
+  {0x14d, 2, 264}, /* LATIN SMALL LETTER O WITH MACRON */
+  {0x14e, 2, 266}, /* LATIN CAPITAL LETTER O WITH BREVE */
+  {0x14f, 2, 268}, /* LATIN SMALL LETTER O WITH BREVE */
+  {0x150, 2, 270}, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+  {0x151, 2, 272}, /* LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+  {0x154, 2, 274}, /* LATIN CAPITAL LETTER R WITH ACUTE */
+  {0x155, 2, 276}, /* LATIN SMALL LETTER R WITH ACUTE */
+  {0x156, 2, 278}, /* LATIN CAPITAL LETTER R WITH CEDILLA */
+  {0x157, 2, 280}, /* LATIN SMALL LETTER R WITH CEDILLA */
+  {0x158, 2, 282}, /* LATIN CAPITAL LETTER R WITH CARON */
+  {0x159, 2, 284}, /* LATIN SMALL LETTER R WITH CARON */
+  {0x15a, 2, 286}, /* LATIN CAPITAL LETTER S WITH ACUTE */
+  {0x15b, 2, 288}, /* LATIN SMALL LETTER S WITH ACUTE */
+  {0x15c, 2, 290}, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+  {0x15d, 2, 292}, /* LATIN SMALL LETTER S WITH CIRCUMFLEX */
+  {0x15e, 2, 294}, /* LATIN CAPITAL LETTER S WITH CEDILLA */
+  {0x15f, 2, 296}, /* LATIN SMALL LETTER S WITH CEDILLA */
+  {0x160, 2, 298}, /* LATIN CAPITAL LETTER S WITH CARON */
+  {0x161, 2, 300}, /* LATIN SMALL LETTER S WITH CARON */
+  {0x162, 2, 302}, /* LATIN CAPITAL LETTER T WITH CEDILLA */
+  {0x163, 2, 304}, /* LATIN SMALL LETTER T WITH CEDILLA */
+  {0x164, 2, 306}, /* LATIN CAPITAL LETTER T WITH CARON */
+  {0x165, 2, 308}, /* LATIN SMALL LETTER T WITH CARON */
+  {0x168, 2, 310}, /* LATIN CAPITAL LETTER U WITH TILDE */
+  {0x169, 2, 312}, /* LATIN SMALL LETTER U WITH TILDE */
+  {0x16a, 2, 314}, /* LATIN CAPITAL LETTER U WITH MACRON */
+  {0x16b, 2, 316}, /* LATIN SMALL LETTER U WITH MACRON */
+  {0x16c, 2, 318}, /* LATIN CAPITAL LETTER U WITH BREVE */
+  {0x16d, 2, 320}, /* LATIN SMALL LETTER U WITH BREVE */
+  {0x16e, 2, 322}, /* LATIN CAPITAL LETTER U WITH RING ABOVE */
+  {0x16f, 2, 324}, /* LATIN SMALL LETTER U WITH RING ABOVE */
+  {0x170, 2, 326}, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+  {0x171, 2, 328}, /* LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+  {0x172, 2, 330}, /* LATIN CAPITAL LETTER U WITH OGONEK */
+  {0x173, 2, 332}, /* LATIN SMALL LETTER U WITH OGONEK */
+  {0x174, 2, 334}, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX */
+  {0x175, 2, 336}, /* LATIN SMALL LETTER W WITH CIRCUMFLEX */
+  {0x176, 2, 338}, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */
+  {0x177, 2, 340}, /* LATIN SMALL LETTER Y WITH CIRCUMFLEX */
+  {0x178, 2, 342}, /* LATIN CAPITAL LETTER Y WITH DIAERESIS */
+  {0x179, 2, 344}, /* LATIN CAPITAL LETTER Z WITH ACUTE */
+  {0x17a, 2, 346}, /* LATIN SMALL LETTER Z WITH ACUTE */
+  {0x17b, 2, 348}, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+  {0x17c, 2, 350}, /* LATIN SMALL LETTER Z WITH DOT ABOVE */
+  {0x17d, 2, 352}, /* LATIN CAPITAL LETTER Z WITH CARON */
+  {0x17e, 2, 354}, /* LATIN SMALL LETTER Z WITH CARON */
+  {0x17f, 1, 288}, /* LATIN SMALL LETTER LONG S */
+  {0x1a0, 2, 356}, /* LATIN CAPITAL LETTER O WITH HORN */
+  {0x1a1, 2, 358}, /* LATIN SMALL LETTER O WITH HORN */
+  {0x1af, 2, 360}, /* LATIN CAPITAL LETTER U WITH HORN */
+  {0x1b0, 2, 362}, /* LATIN SMALL LETTER U WITH HORN */
+  {0x1c4, 2, 364}, /* LATIN CAPITAL LETTER DZ WITH CARON */
+  {0x1c5, 2, 366}, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON */
+  {0x1c6, 2, 368}, /* LATIN SMALL LETTER DZ WITH CARON */
+  {0x1c7, 2, 370}, /* LATIN CAPITAL LETTER LJ */
+  {0x1c8, 2, 372}, /* LATIN CAPITAL LETTER L WITH SMALL LETTER J */
+  {0x1c9, 2, 374}, /* LATIN SMALL LETTER LJ */
+  {0x1ca, 2, 376}, /* LATIN CAPITAL LETTER NJ */
+  {0x1cb, 2, 378}, /* LATIN CAPITAL LETTER N WITH SMALL LETTER J */
+  {0x1cc, 2, 380}, /* LATIN SMALL LETTER NJ */
+  {0x1cd, 2, 382}, /* LATIN CAPITAL LETTER A WITH CARON */
+  {0x1ce, 2, 384}, /* LATIN SMALL LETTER A WITH CARON */
+  {0x1cf, 2, 386}, /* LATIN CAPITAL LETTER I WITH CARON */
+  {0x1d0, 2, 388}, /* LATIN SMALL LETTER I WITH CARON */
+  {0x1d1, 2, 390}, /* LATIN CAPITAL LETTER O WITH CARON */
+  {0x1d2, 2, 392}, /* LATIN SMALL LETTER O WITH CARON */
+  {0x1d3, 2, 394}, /* LATIN CAPITAL LETTER U WITH CARON */
+  {0x1d4, 2, 396}, /* LATIN SMALL LETTER U WITH CARON */
+  {0x1d5, 2, 398}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON */
+  {0x1d6, 2, 400}, /* LATIN SMALL LETTER U WITH DIAERESIS AND MACRON */
+  {0x1d7, 2, 402}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE */
+  {0x1d8, 2, 404}, /* LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE */
+  {0x1d9, 2, 406}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON */
+  {0x1da, 2, 408}, /* LATIN SMALL LETTER U WITH DIAERESIS AND CARON */
+  {0x1db, 2, 410}, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE */
+  {0x1dc, 2, 412}, /* LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE */
+  {0x1de, 2, 414}, /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON */
+  {0x1df, 2, 416}, /* LATIN SMALL LETTER A WITH DIAERESIS AND MACRON */
+  {0x1e0, 2, 418}, /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON */
+  {0x1e1, 2, 420}, /* LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON */
+  {0x1e2, 2, 422}, /* LATIN CAPITAL LETTER AE WITH MACRON */
+  {0x1e3, 2, 424}, /* LATIN SMALL LETTER AE WITH MACRON */
+  {0x1e6, 2, 426}, /* LATIN CAPITAL LETTER G WITH CARON */
+  {0x1e7, 2, 428}, /* LATIN SMALL LETTER G WITH CARON */
+  {0x1e8, 2, 430}, /* LATIN CAPITAL LETTER K WITH CARON */
+  {0x1e9, 2, 432}, /* LATIN SMALL LETTER K WITH CARON */
+  {0x1ea, 2, 434}, /* LATIN CAPITAL LETTER O WITH OGONEK */
+  {0x1eb, 2, 436}, /* LATIN SMALL LETTER O WITH OGONEK */
+  {0x1ec, 2, 438}, /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON */
+  {0x1ed, 2, 440}, /* LATIN SMALL LETTER O WITH OGONEK AND MACRON */
+  {0x1ee, 2, 442}, /* LATIN CAPITAL LETTER EZH WITH CARON */
+  {0x1ef, 2, 444}, /* LATIN SMALL LETTER EZH WITH CARON */
+  {0x1f0, 2, 446}, /* LATIN SMALL LETTER J WITH CARON */
+  {0x1f1, 2, 448}, /* LATIN CAPITAL LETTER DZ */
+  {0x1f2, 2, 450}, /* LATIN CAPITAL LETTER D WITH SMALL LETTER Z */
+  {0x1f3, 2, 452}, /* LATIN SMALL LETTER DZ */
+  {0x1f4, 2, 454}, /* LATIN CAPITAL LETTER G WITH ACUTE */
+  {0x1f5, 2, 456}, /* LATIN SMALL LETTER G WITH ACUTE */
+  {0x1f8, 2, 458}, /* LATIN CAPITAL LETTER N WITH GRAVE */
+  {0x1f9, 2, 460}, /* LATIN SMALL LETTER N WITH GRAVE */
+  {0x1fa, 2, 462}, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE */
+  {0x1fb, 2, 464}, /* LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE */
+  {0x1fc, 2, 466}, /* LATIN CAPITAL LETTER AE WITH ACUTE */
+  {0x1fd, 2, 468}, /* LATIN SMALL LETTER AE WITH ACUTE */
+  {0x1fe, 2, 470}, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE */
+  {0x1ff, 2, 472}, /* LATIN SMALL LETTER O WITH STROKE AND ACUTE */
+  {0x200, 2, 474}, /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE */
+  {0x201, 2, 476}, /* LATIN SMALL LETTER A WITH DOUBLE GRAVE */
+  {0x202, 2, 478}, /* LATIN CAPITAL LETTER A WITH INVERTED BREVE */
+  {0x203, 2, 480}, /* LATIN SMALL LETTER A WITH INVERTED BREVE */
+  {0x204, 2, 482}, /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE */
+  {0x205, 2, 484}, /* LATIN SMALL LETTER E WITH DOUBLE GRAVE */
+  {0x206, 2, 486}, /* LATIN CAPITAL LETTER E WITH INVERTED BREVE */
+  {0x207, 2, 488}, /* LATIN SMALL LETTER E WITH INVERTED BREVE */
+  {0x208, 2, 490}, /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE */
+  {0x209, 2, 492}, /* LATIN SMALL LETTER I WITH DOUBLE GRAVE */
+  {0x20a, 2, 494}, /* LATIN CAPITAL LETTER I WITH INVERTED BREVE */
+  {0x20b, 2, 496}, /* LATIN SMALL LETTER I WITH INVERTED BREVE */
+  {0x20c, 2, 498}, /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE */
+  {0x20d, 2, 500}, /* LATIN SMALL LETTER O WITH DOUBLE GRAVE */
+  {0x20e, 2, 502}, /* LATIN CAPITAL LETTER O WITH INVERTED BREVE */
+  {0x20f, 2, 504}, /* LATIN SMALL LETTER O WITH INVERTED BREVE */
+  {0x210, 2, 506}, /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE */
+  {0x211, 2, 508}, /* LATIN SMALL LETTER R WITH DOUBLE GRAVE */
+  {0x212, 2, 510}, /* LATIN CAPITAL LETTER R WITH INVERTED BREVE */
+  {0x213, 2, 512}, /* LATIN SMALL LETTER R WITH INVERTED BREVE */
+  {0x214, 2, 514}, /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE */
+  {0x215, 2, 516}, /* LATIN SMALL LETTER U WITH DOUBLE GRAVE */
+  {0x216, 2, 518}, /* LATIN CAPITAL LETTER U WITH INVERTED BREVE */
+  {0x217, 2, 520}, /* LATIN SMALL LETTER U WITH INVERTED BREVE */
+  {0x218, 2, 522}, /* LATIN CAPITAL LETTER S WITH COMMA BELOW */
+  {0x219, 2, 524}, /* LATIN SMALL LETTER S WITH COMMA BELOW */
+  {0x21a, 2, 526}, /* LATIN CAPITAL LETTER T WITH COMMA BELOW */
+  {0x21b, 2, 528}, /* LATIN SMALL LETTER T WITH COMMA BELOW */
+  {0x21e, 2, 530}, /* LATIN CAPITAL LETTER H WITH CARON */
+  {0x21f, 2, 532}, /* LATIN SMALL LETTER H WITH CARON */
+  {0x226, 2, 534}, /* LATIN CAPITAL LETTER A WITH DOT ABOVE */
+  {0x227, 2, 536}, /* LATIN SMALL LETTER A WITH DOT ABOVE */
+  {0x228, 2, 538}, /* LATIN CAPITAL LETTER E WITH CEDILLA */
+  {0x229, 2, 540}, /* LATIN SMALL LETTER E WITH CEDILLA */
+  {0x22a, 2, 542}, /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON */
+  {0x22b, 2, 544}, /* LATIN SMALL LETTER O WITH DIAERESIS AND MACRON */
+  {0x22c, 2, 546}, /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON */
+  {0x22d, 2, 548}, /* LATIN SMALL LETTER O WITH TILDE AND MACRON */
+  {0x22e, 2, 550}, /* LATIN CAPITAL LETTER O WITH DOT ABOVE */
+  {0x22f, 2, 552}, /* LATIN SMALL LETTER O WITH DOT ABOVE */
+  {0x230, 2, 554}, /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON */
+  {0x231, 2, 556}, /* LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON */
+  {0x232, 2, 558}, /* LATIN CAPITAL LETTER Y WITH MACRON */
+  {0x233, 2, 560}, /* LATIN SMALL LETTER Y WITH MACRON */
+  {0x2b0, 1, 200}, /* MODIFIER LETTER SMALL H */
+  {0x2b1, 1, 562}, /* MODIFIER LETTER SMALL H WITH HOOK */
+  {0x2b2, 1, 223}, /* MODIFIER LETTER SMALL J */
+  {0x2b3, 1, 276}, /* MODIFIER LETTER SMALL R */
+  {0x2b4, 1, 563}, /* MODIFIER LETTER SMALL TURNED R */
+  {0x2b5, 1, 564}, /* MODIFIER LETTER SMALL TURNED R WITH HOOK */
+  {0x2b6, 1, 565}, /* MODIFIER LETTER SMALL CAPITAL INVERTED R */
+  {0x2b7, 1, 336}, /* MODIFIER LETTER SMALL W */
+  {0x2b8, 1, 126}, /* MODIFIER LETTER SMALL Y */
+  {0x2d8, 2, 566}, /* BREVE */
+  {0x2d9, 2, 568}, /* DOT ABOVE */
+  {0x2da, 2, 570}, /* RING ABOVE */
+  {0x2db, 2, 572}, /* OGONEK */
+  {0x2dc, 2, 574}, /* SMALL TILDE */
+  {0x2dd, 2, 576}, /* DOUBLE ACUTE ACCENT */
+  {0x2e0, 1, 578}, /* MODIFIER LETTER SMALL GAMMA */
+  {0x2e1, 1, 234}, /* MODIFIER LETTER SMALL L */
+  {0x2e2, 1, 288}, /* MODIFIER LETTER SMALL S */
+  {0x2e3, 1, 579}, /* MODIFIER LETTER SMALL X */
+  {0x2e4, 1, 580}, /* MODIFIER LETTER SMALL REVERSED GLOTTAL STOP */
+  {0x340, 1, 25}, /* COMBINING GRAVE TONE MARK */
+  {0x341, 1, 9}, /* COMBINING ACUTE TONE MARK */
+  {0x343, 1, 581}, /* COMBINING GREEK KORONIS */
+  {0x344, 2, 582}, /* COMBINING GREEK DIALYTIKA TONOS */
+  {0x374, 1, 584}, /* GREEK NUMERAL SIGN */
+  {0x37a, 2, 585}, /* GREEK YPOGEGRAMMENI */
+  {0x37e, 1, 587}, /* GREEK QUESTION MARK */
+  {0x384, 2, 8}, /* GREEK TONOS */
+  {0x385, 2, 588}, /* GREEK DIALYTIKA TONOS */
+  {0x386, 2, 590}, /* GREEK CAPITAL LETTER ALPHA WITH TONOS */
+  {0x387, 1, 245}, /* GREEK ANO TELEIA */
+  {0x388, 2, 592}, /* GREEK CAPITAL LETTER EPSILON WITH TONOS */
+  {0x389, 2, 594}, /* GREEK CAPITAL LETTER ETA WITH TONOS */
+  {0x38a, 2, 596}, /* GREEK CAPITAL LETTER IOTA WITH TONOS */
+  {0x38c, 2, 598}, /* GREEK CAPITAL LETTER OMICRON WITH TONOS */
+  {0x38e, 2, 600}, /* GREEK CAPITAL LETTER UPSILON WITH TONOS */
+  {0x38f, 2, 602}, /* GREEK CAPITAL LETTER OMEGA WITH TONOS */
+  {0x390, 2, 604}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+  {0x3aa, 2, 606}, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+  {0x3ab, 2, 608}, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+  {0x3ac, 2, 610}, /* GREEK SMALL LETTER ALPHA WITH TONOS */
+  {0x3ad, 2, 612}, /* GREEK SMALL LETTER EPSILON WITH TONOS */
+  {0x3ae, 2, 614}, /* GREEK SMALL LETTER ETA WITH TONOS */
+  {0x3af, 2, 616}, /* GREEK SMALL LETTER IOTA WITH TONOS */
+  {0x3b0, 2, 618}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+  {0x3ca, 2, 620}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+  {0x3cb, 2, 622}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+  {0x3cc, 2, 624}, /* GREEK SMALL LETTER OMICRON WITH TONOS */
+  {0x3cd, 2, 626}, /* GREEK SMALL LETTER UPSILON WITH TONOS */
+  {0x3ce, 2, 628}, /* GREEK SMALL LETTER OMEGA WITH TONOS */
+  {0x3d0, 1, 630}, /* GREEK BETA SYMBOL */
+  {0x3d1, 1, 631}, /* GREEK THETA SYMBOL */
+  {0x3d2, 1, 600}, /* GREEK UPSILON WITH HOOK SYMBOL */
+  {0x3d3, 2, 632}, /* GREEK UPSILON WITH ACUTE AND HOOK SYMBOL */
+  {0x3d4, 2, 634}, /* GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL */
+  {0x3d5, 1, 636}, /* GREEK PHI SYMBOL */
+  {0x3d6, 1, 637}, /* GREEK PI SYMBOL */
+  {0x3f0, 1, 638}, /* GREEK KAPPA SYMBOL */
+  {0x3f1, 1, 639}, /* GREEK RHO SYMBOL */
+  {0x3f2, 1, 640}, /* GREEK LUNATE SIGMA SYMBOL */
+  {0x3f4, 1, 641}, /* GREEK CAPITAL THETA SYMBOL */
+  {0x3f5, 1, 612}, /* GREEK LUNATE EPSILON SYMBOL */
+  {0x3f9, 1, 642}, /* GREEK CAPITAL LUNATE SIGMA SYMBOL */
+  {0x400, 2, 643}, /* CYRILLIC CAPITAL LETTER IE WITH GRAVE */
+  {0x401, 2, 645}, /* CYRILLIC CAPITAL LETTER IO */
+  {0x403, 2, 647}, /* CYRILLIC CAPITAL LETTER GJE */
+  {0x407, 2, 649}, /* CYRILLIC CAPITAL LETTER YI */
+  {0x40c, 2, 651}, /* CYRILLIC CAPITAL LETTER KJE */
+  {0x40d, 2, 653}, /* CYRILLIC CAPITAL LETTER I WITH GRAVE */
+  {0x40e, 2, 655}, /* CYRILLIC CAPITAL LETTER SHORT U */
+  {0x419, 2, 657}, /* CYRILLIC CAPITAL LETTER SHORT I */
+  {0x439, 2, 659}, /* CYRILLIC SMALL LETTER SHORT I */
+  {0x450, 2, 661}, /* CYRILLIC SMALL LETTER IE WITH GRAVE */
+  {0x451, 2, 663}, /* CYRILLIC SMALL LETTER IO */
+  {0x453, 2, 665}, /* CYRILLIC SMALL LETTER GJE */
+  {0x457, 2, 667}, /* CYRILLIC SMALL LETTER YI */
+  {0x45c, 2, 669}, /* CYRILLIC SMALL LETTER KJE */
+  {0x45d, 2, 671}, /* CYRILLIC SMALL LETTER I WITH GRAVE */
+  {0x45e, 2, 673}, /* CYRILLIC SMALL LETTER SHORT U */
+  {0x476, 2, 675}, /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
+  {0x477, 2, 677}, /* CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT */
+  {0x4c1, 2, 679}, /* CYRILLIC CAPITAL LETTER ZHE WITH BREVE */
+  {0x4c2, 2, 681}, /* CYRILLIC SMALL LETTER ZHE WITH BREVE */
+  {0x4d0, 2, 683}, /* CYRILLIC CAPITAL LETTER A WITH BREVE */
+  {0x4d1, 2, 685}, /* CYRILLIC SMALL LETTER A WITH BREVE */
+  {0x4d2, 2, 687}, /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS */
+  {0x4d3, 2, 689}, /* CYRILLIC SMALL LETTER A WITH DIAERESIS */
+  {0x4d6, 2, 691}, /* CYRILLIC CAPITAL LETTER IE WITH BREVE */
+  {0x4d7, 2, 693}, /* CYRILLIC SMALL LETTER IE WITH BREVE */
+  {0x4da, 2, 695}, /* CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS */
+  {0x4db, 2, 697}, /* CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS */
+  {0x4dc, 2, 699}, /* CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS */
+  {0x4dd, 2, 701}, /* CYRILLIC SMALL LETTER ZHE WITH DIAERESIS */
+  {0x4de, 2, 703}, /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS */
+  {0x4df, 2, 705}, /* CYRILLIC SMALL LETTER ZE WITH DIAERESIS */
+  {0x4e2, 2, 707}, /* CYRILLIC CAPITAL LETTER I WITH MACRON */
+  {0x4e3, 2, 709}, /* CYRILLIC SMALL LETTER I WITH MACRON */
+  {0x4e4, 2, 711}, /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS */
+  {0x4e5, 2, 713}, /* CYRILLIC SMALL LETTER I WITH DIAERESIS */
+  {0x4e6, 2, 715}, /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS */
+  {0x4e7, 2, 717}, /* CYRILLIC SMALL LETTER O WITH DIAERESIS */
+  {0x4ea, 2, 719}, /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS */
+  {0x4eb, 2, 721}, /* CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS */
+  {0x4ec, 2, 723}, /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS */
+  {0x4ed, 2, 725}, /* CYRILLIC SMALL LETTER E WITH DIAERESIS */
+  {0x4ee, 2, 727}, /* CYRILLIC CAPITAL LETTER U WITH MACRON */
+  {0x4ef, 2, 729}, /* CYRILLIC SMALL LETTER U WITH MACRON */
+  {0x4f0, 2, 731}, /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS */
+  {0x4f1, 2, 733}, /* CYRILLIC SMALL LETTER U WITH DIAERESIS */
+  {0x4f2, 2, 735}, /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE */
+  {0x4f3, 2, 737}, /* CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE */
+  {0x4f4, 2, 739}, /* CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS */
+  {0x4f5, 2, 741}, /* CYRILLIC SMALL LETTER CHE WITH DIAERESIS */
+  {0x4f8, 2, 743}, /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS */
+  {0x4f9, 2, 745}, /* CYRILLIC SMALL LETTER YERU WITH DIAERESIS */
+  {0x587, 2, 747}, /* ARMENIAN SMALL LIGATURE ECH YIWN */
+  {0x622, 2, 749}, /* ARABIC LETTER ALEF WITH MADDA ABOVE */
+  {0x623, 2, 751}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE */
+  {0x624, 2, 753}, /* ARABIC LETTER WAW WITH HAMZA ABOVE */
+  {0x625, 2, 755}, /* ARABIC LETTER ALEF WITH HAMZA BELOW */
+  {0x626, 2, 757}, /* ARABIC LETTER YEH WITH HAMZA ABOVE */
+  {0x675, 2, 759}, /* ARABIC LETTER HIGH HAMZA ALEF */
+  {0x676, 2, 761}, /* ARABIC LETTER HIGH HAMZA WAW */
+  {0x677, 2, 763}, /* ARABIC LETTER U WITH HAMZA ABOVE */
+  {0x678, 2, 765}, /* ARABIC LETTER HIGH HAMZA YEH */
+  {0x6c0, 2, 767}, /* ARABIC LETTER HEH WITH YEH ABOVE */
+  {0x6c2, 2, 769}, /* ARABIC LETTER HEH GOAL WITH HAMZA ABOVE */
+  {0x6d3, 2, 771}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE */
+  {0x929, 2, 773}, /* DEVANAGARI LETTER NNNA */
+  {0x931, 2, 775}, /* DEVANAGARI LETTER RRA */
+  {0x934, 2, 777}, /* DEVANAGARI LETTER LLLA */
+  {0x958, 2, 779}, /* DEVANAGARI LETTER QA */
+  {0x959, 2, 781}, /* DEVANAGARI LETTER KHHA */
+  {0x95a, 2, 783}, /* DEVANAGARI LETTER GHHA */
+  {0x95b, 2, 785}, /* DEVANAGARI LETTER ZA */
+  {0x95c, 2, 787}, /* DEVANAGARI LETTER DDDHA */
+  {0x95d, 2, 789}, /* DEVANAGARI LETTER RHA */
+  {0x95e, 2, 791}, /* DEVANAGARI LETTER FA */
+  {0x95f, 2, 793}, /* DEVANAGARI LETTER YYA */
+  {0x9cb, 2, 795}, /* BENGALI VOWEL SIGN O */
+  {0x9cc, 2, 797}, /* BENGALI VOWEL SIGN AU */
+  {0x9dc, 2, 799}, /* BENGALI LETTER RRA */
+  {0x9dd, 2, 801}, /* BENGALI LETTER RHA */
+  {0x9df, 2, 803}, /* BENGALI LETTER YYA */
+  {0xa33, 2, 805}, /* GURMUKHI LETTER LLA */
+  {0xa36, 2, 807}, /* GURMUKHI LETTER SHA */
+  {0xa59, 2, 809}, /* GURMUKHI LETTER KHHA */
+  {0xa5a, 2, 811}, /* GURMUKHI LETTER GHHA */
+  {0xa5b, 2, 813}, /* GURMUKHI LETTER ZA */
+  {0xa5e, 2, 815}, /* GURMUKHI LETTER FA */
+  {0xb48, 2, 817}, /* ORIYA VOWEL SIGN AI */
+  {0xb4b, 2, 819}, /* ORIYA VOWEL SIGN O */
+  {0xb4c, 2, 821}, /* ORIYA VOWEL SIGN AU */
+  {0xb5c, 2, 823}, /* ORIYA LETTER RRA */
+  {0xb5d, 2, 825}, /* ORIYA LETTER RHA */
+  {0xb94, 2, 827}, /* TAMIL LETTER AU */
+  {0xbca, 2, 829}, /* TAMIL VOWEL SIGN O */
+  {0xbcb, 2, 831}, /* TAMIL VOWEL SIGN OO */
+  {0xbcc, 2, 833}, /* TAMIL VOWEL SIGN AU */
+  {0xc48, 2, 835}, /* TELUGU VOWEL SIGN AI */
+  {0xcc0, 2, 837}, /* KANNADA VOWEL SIGN II */
+  {0xcc7, 2, 839}, /* KANNADA VOWEL SIGN EE */
+  {0xcc8, 2, 841}, /* KANNADA VOWEL SIGN AI */
+  {0xcca, 2, 843}, /* KANNADA VOWEL SIGN O */
+  {0xccb, 2, 845}, /* KANNADA VOWEL SIGN OO */
+  {0xd4a, 2, 847}, /* MALAYALAM VOWEL SIGN O */
+  {0xd4b, 2, 849}, /* MALAYALAM VOWEL SIGN OO */
+  {0xd4c, 2, 851}, /* MALAYALAM VOWEL SIGN AU */
+  {0xdda, 2, 853}, /* SINHALA VOWEL SIGN DIGA KOMBUVA */
+  {0xddc, 2, 855}, /* SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA */
+  {0xddd, 2, 857}, /* SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA */
+  {0xdde, 2, 859}, /* SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA */
+  {0xe33, 2, 861}, /* THAI CHARACTER SARA AM */
+  {0xeb3, 2, 863}, /* LAO VOWEL SIGN AM */
+  {0xedc, 2, 865}, /* LAO HO NO */
+  {0xedd, 2, 867}, /* LAO HO MO */
+  {0xf0c, 1, 869}, /* TIBETAN MARK DELIMITER TSHEG BSTAR */
+  {0xf43, 2, 870}, /* TIBETAN LETTER GHA */
+  {0xf4d, 2, 872}, /* TIBETAN LETTER DDHA */
+  {0xf52, 2, 874}, /* TIBETAN LETTER DHA */
+  {0xf57, 2, 876}, /* TIBETAN LETTER BHA */
+  {0xf5c, 2, 878}, /* TIBETAN LETTER DZHA */
+  {0xf69, 2, 880}, /* TIBETAN LETTER KSSA */
+  {0xf73, 2, 882}, /* TIBETAN VOWEL SIGN II */
+  {0xf75, 2, 884}, /* TIBETAN VOWEL SIGN UU */
+  {0xf76, 2, 886}, /* TIBETAN VOWEL SIGN VOCALIC R */
+  {0xf77, 2, 888}, /* TIBETAN VOWEL SIGN VOCALIC RR */
+  {0xf78, 2, 890}, /* TIBETAN VOWEL SIGN VOCALIC L */
+  {0xf79, 2, 892}, /* TIBETAN VOWEL SIGN VOCALIC LL */
+  {0xf81, 2, 894}, /* TIBETAN VOWEL SIGN REVERSED II */
+  {0xf93, 2, 896}, /* TIBETAN SUBJOINED LETTER GHA */
+  {0xf9d, 2, 898}, /* TIBETAN SUBJOINED LETTER DDHA */
+  {0xfa2, 2, 900}, /* TIBETAN SUBJOINED LETTER DHA */
+  {0xfa7, 2, 902}, /* TIBETAN SUBJOINED LETTER BHA */
+  {0xfac, 2, 904}, /* TIBETAN SUBJOINED LETTER DZHA */
+  {0xfb9, 2, 906}, /* TIBETAN SUBJOINED LETTER KSSA */
+  {0x1026, 2, 908}, /* MYANMAR LETTER UU */
+  {0x1d2c, 1, 24}, /* MODIFIER LETTER CAPITAL A */
+  {0x1d2d, 1, 422}, /* MODIFIER LETTER CAPITAL AE */
+  {0x1d2e, 1, 910}, /* MODIFIER LETTER CAPITAL B */
+  {0x1d30, 1, 158}, /* MODIFIER LETTER CAPITAL D */
+  {0x1d31, 1, 38}, /* MODIFIER LETTER CAPITAL E */
+  {0x1d32, 1, 911}, /* MODIFIER LETTER CAPITAL REVERSED E */
+  {0x1d33, 1, 182}, /* MODIFIER LETTER CAPITAL G */
+  {0x1d34, 1, 198}, /* MODIFIER LETTER CAPITAL H */
+  {0x1d35, 1, 46}, /* MODIFIER LETTER CAPITAL I */
+  {0x1d36, 1, 221}, /* MODIFIER LETTER CAPITAL J */
+  {0x1d37, 1, 228}, /* MODIFIER LETTER CAPITAL K */
+  {0x1d38, 1, 232}, /* MODIFIER LETTER CAPITAL L */
+  {0x1d39, 1, 912}, /* MODIFIER LETTER CAPITAL M */
+  {0x1d3a, 1, 54}, /* MODIFIER LETTER CAPITAL N */
+  {0x1d3c, 1, 56}, /* MODIFIER LETTER CAPITAL O */
+  {0x1d3d, 1, 913}, /* MODIFIER LETTER CAPITAL OU */
+  {0x1d3e, 1, 914}, /* MODIFIER LETTER CAPITAL P */
+  {0x1d3f, 1, 274}, /* MODIFIER LETTER CAPITAL R */
+  {0x1d40, 1, 302}, /* MODIFIER LETTER CAPITAL T */
+  {0x1d41, 1, 66}, /* MODIFIER LETTER CAPITAL U */
+  {0x1d42, 1, 334}, /* MODIFIER LETTER CAPITAL W */
+  {0x1d43, 1, 3}, /* MODIFIER LETTER SMALL A */
+  {0x1d44, 1, 915}, /* MODIFIER LETTER SMALL TURNED A */
+  {0x1d45, 1, 916}, /* MODIFIER LETTER SMALL ALPHA */
+  {0x1d46, 1, 917}, /* MODIFIER LETTER SMALL TURNED AE */
+  {0x1d47, 1, 918}, /* MODIFIER LETTER SMALL B */
+  {0x1d48, 1, 160}, /* MODIFIER LETTER SMALL D */
+  {0x1d49, 1, 90}, /* MODIFIER LETTER SMALL E */
+  {0x1d4a, 1, 919}, /* MODIFIER LETTER SMALL SCHWA */
+  {0x1d4b, 1, 920}, /* MODIFIER LETTER SMALL OPEN E */
+  {0x1d4c, 1, 921}, /* MODIFIER LETTER SMALL TURNED OPEN E */
+  {0x1d4d, 1, 184}, /* MODIFIER LETTER SMALL G */
+  {0x1d4f, 1, 230}, /* MODIFIER LETTER SMALL K */
+  {0x1d50, 1, 922}, /* MODIFIER LETTER SMALL M */
+  {0x1d51, 1, 923}, /* MODIFIER LETTER SMALL ENG */
+  {0x1d52, 1, 14}, /* MODIFIER LETTER SMALL O */
+  {0x1d53, 1, 924}, /* MODIFIER LETTER SMALL OPEN O */
+  {0x1d54, 1, 925}, /* MODIFIER LETTER SMALL TOP HALF O */
+  {0x1d55, 1, 926}, /* MODIFIER LETTER SMALL BOTTOM HALF O */
+  {0x1d56, 1, 927}, /* MODIFIER LETTER SMALL P */
+  {0x1d57, 1, 304}, /* MODIFIER LETTER SMALL T */
+  {0x1d58, 1, 118}, /* MODIFIER LETTER SMALL U */
+  {0x1d59, 1, 928}, /* MODIFIER LETTER SMALL SIDEWAYS U */
+  {0x1d5a, 1, 929}, /* MODIFIER LETTER SMALL TURNED M */
+  {0x1d5b, 1, 930}, /* MODIFIER LETTER SMALL V */
+  {0x1d5c, 1, 931}, /* MODIFIER LETTER SMALL AIN */
+  {0x1d5d, 1, 630}, /* MODIFIER LETTER SMALL BETA */
+  {0x1d5e, 1, 932}, /* MODIFIER LETTER SMALL GREEK GAMMA */
+  {0x1d5f, 1, 933}, /* MODIFIER LETTER SMALL DELTA */
+  {0x1d60, 1, 636}, /* MODIFIER LETTER SMALL GREEK PHI */
+  {0x1d61, 1, 934}, /* MODIFIER LETTER SMALL CHI */
+  {0x1d62, 1, 98}, /* LATIN SUBSCRIPT SMALL LETTER I */
+  {0x1d63, 1, 276}, /* LATIN SUBSCRIPT SMALL LETTER R */
+  {0x1d64, 1, 118}, /* LATIN SUBSCRIPT SMALL LETTER U */
+  {0x1d65, 1, 930}, /* LATIN SUBSCRIPT SMALL LETTER V */
+  {0x1d66, 1, 630}, /* GREEK SUBSCRIPT SMALL LETTER BETA */
+  {0x1d67, 1, 932}, /* GREEK SUBSCRIPT SMALL LETTER GAMMA */
+  {0x1d68, 1, 639}, /* GREEK SUBSCRIPT SMALL LETTER RHO */
+  {0x1d69, 1, 636}, /* GREEK SUBSCRIPT SMALL LETTER PHI */
+  {0x1d6a, 1, 934}, /* GREEK SUBSCRIPT SMALL LETTER CHI */
+  {0x1e00, 2, 935}, /* LATIN CAPITAL LETTER A WITH RING BELOW */
+  {0x1e01, 2, 937}, /* LATIN SMALL LETTER A WITH RING BELOW */
+  {0x1e02, 2, 939}, /* LATIN CAPITAL LETTER B WITH DOT ABOVE */
+  {0x1e03, 2, 941}, /* LATIN SMALL LETTER B WITH DOT ABOVE */
+  {0x1e04, 2, 943}, /* LATIN CAPITAL LETTER B WITH DOT BELOW */
+  {0x1e05, 2, 945}, /* LATIN SMALL LETTER B WITH DOT BELOW */
+  {0x1e06, 2, 947}, /* LATIN CAPITAL LETTER B WITH LINE BELOW */
+  {0x1e07, 2, 949}, /* LATIN SMALL LETTER B WITH LINE BELOW */
+  {0x1e08, 2, 951}, /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE */
+  {0x1e09, 2, 953}, /* LATIN SMALL LETTER C WITH CEDILLA AND ACUTE */
+  {0x1e0a, 2, 955}, /* LATIN CAPITAL LETTER D WITH DOT ABOVE */
+  {0x1e0b, 2, 957}, /* LATIN SMALL LETTER D WITH DOT ABOVE */
+  {0x1e0c, 2, 959}, /* LATIN CAPITAL LETTER D WITH DOT BELOW */
+  {0x1e0d, 2, 961}, /* LATIN SMALL LETTER D WITH DOT BELOW */
+  {0x1e0e, 2, 963}, /* LATIN CAPITAL LETTER D WITH LINE BELOW */
+  {0x1e0f, 2, 965}, /* LATIN SMALL LETTER D WITH LINE BELOW */
+  {0x1e10, 2, 967}, /* LATIN CAPITAL LETTER D WITH CEDILLA */
+  {0x1e11, 2, 969}, /* LATIN SMALL LETTER D WITH CEDILLA */
+  {0x1e12, 2, 971}, /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW */
+  {0x1e13, 2, 973}, /* LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW */
+  {0x1e14, 2, 975}, /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE */
+  {0x1e15, 2, 977}, /* LATIN SMALL LETTER E WITH MACRON AND GRAVE */
+  {0x1e16, 2, 979}, /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE */
+  {0x1e17, 2, 981}, /* LATIN SMALL LETTER E WITH MACRON AND ACUTE */
+  {0x1e18, 2, 983}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW */
+  {0x1e19, 2, 985}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW */
+  {0x1e1a, 2, 987}, /* LATIN CAPITAL LETTER E WITH TILDE BELOW */
+  {0x1e1b, 2, 989}, /* LATIN SMALL LETTER E WITH TILDE BELOW */
+  {0x1e1c, 2, 991}, /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE */
+  {0x1e1d, 2, 993}, /* LATIN SMALL LETTER E WITH CEDILLA AND BREVE */
+  {0x1e1e, 2, 995}, /* LATIN CAPITAL LETTER F WITH DOT ABOVE */
+  {0x1e1f, 2, 997}, /* LATIN SMALL LETTER F WITH DOT ABOVE */
+  {0x1e20, 2, 999}, /* LATIN CAPITAL LETTER G WITH MACRON */
+  {0x1e21, 2, 1001}, /* LATIN SMALL LETTER G WITH MACRON */
+  {0x1e22, 2, 1003}, /* LATIN CAPITAL LETTER H WITH DOT ABOVE */
+  {0x1e23, 2, 1005}, /* LATIN SMALL LETTER H WITH DOT ABOVE */
+  {0x1e24, 2, 1007}, /* LATIN CAPITAL LETTER H WITH DOT BELOW */
+  {0x1e25, 2, 1009}, /* LATIN SMALL LETTER H WITH DOT BELOW */
+  {0x1e26, 2, 1011}, /* LATIN CAPITAL LETTER H WITH DIAERESIS */
+  {0x1e27, 2, 1013}, /* LATIN SMALL LETTER H WITH DIAERESIS */
+  {0x1e28, 2, 1015}, /* LATIN CAPITAL LETTER H WITH CEDILLA */
+  {0x1e29, 2, 1017}, /* LATIN SMALL LETTER H WITH CEDILLA */
+  {0x1e2a, 2, 1019}, /* LATIN CAPITAL LETTER H WITH BREVE BELOW */
+  {0x1e2b, 2, 1021}, /* LATIN SMALL LETTER H WITH BREVE BELOW */
+  {0x1e2c, 2, 1023}, /* LATIN CAPITAL LETTER I WITH TILDE BELOW */
+  {0x1e2d, 2, 1025}, /* LATIN SMALL LETTER I WITH TILDE BELOW */
+  {0x1e2e, 2, 1027}, /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE */
+  {0x1e2f, 2, 1029}, /* LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE */
+  {0x1e30, 2, 1031}, /* LATIN CAPITAL LETTER K WITH ACUTE */
+  {0x1e31, 2, 1033}, /* LATIN SMALL LETTER K WITH ACUTE */
+  {0x1e32, 2, 1035}, /* LATIN CAPITAL LETTER K WITH DOT BELOW */
+  {0x1e33, 2, 1037}, /* LATIN SMALL LETTER K WITH DOT BELOW */
+  {0x1e34, 2, 1039}, /* LATIN CAPITAL LETTER K WITH LINE BELOW */
+  {0x1e35, 2, 1041}, /* LATIN SMALL LETTER K WITH LINE BELOW */
+  {0x1e36, 2, 1043}, /* LATIN CAPITAL LETTER L WITH DOT BELOW */
+  {0x1e37, 2, 1045}, /* LATIN SMALL LETTER L WITH DOT BELOW */
+  {0x1e38, 2, 1047}, /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON */
+  {0x1e39, 2, 1049}, /* LATIN SMALL LETTER L WITH DOT BELOW AND MACRON */
+  {0x1e3a, 2, 1051}, /* LATIN CAPITAL LETTER L WITH LINE BELOW */
+  {0x1e3b, 2, 1053}, /* LATIN SMALL LETTER L WITH LINE BELOW */
+  {0x1e3c, 2, 1055}, /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW */
+  {0x1e3d, 2, 1057}, /* LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW */
+  {0x1e3e, 2, 1059}, /* LATIN CAPITAL LETTER M WITH ACUTE */
+  {0x1e3f, 2, 1061}, /* LATIN SMALL LETTER M WITH ACUTE */
+  {0x1e40, 2, 1063}, /* LATIN CAPITAL LETTER M WITH DOT ABOVE */
+  {0x1e41, 2, 1065}, /* LATIN SMALL LETTER M WITH DOT ABOVE */
+  {0x1e42, 2, 1067}, /* LATIN CAPITAL LETTER M WITH DOT BELOW */
+  {0x1e43, 2, 1069}, /* LATIN SMALL LETTER M WITH DOT BELOW */
+  {0x1e44, 2, 1071}, /* LATIN CAPITAL LETTER N WITH DOT ABOVE */
+  {0x1e45, 2, 1073}, /* LATIN SMALL LETTER N WITH DOT ABOVE */
+  {0x1e46, 2, 1075}, /* LATIN CAPITAL LETTER N WITH DOT BELOW */
+  {0x1e47, 2, 1077}, /* LATIN SMALL LETTER N WITH DOT BELOW */
+  {0x1e48, 2, 1079}, /* LATIN CAPITAL LETTER N WITH LINE BELOW */
+  {0x1e49, 2, 1081}, /* LATIN SMALL LETTER N WITH LINE BELOW */
+  {0x1e4a, 2, 1083}, /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW */
+  {0x1e4b, 2, 1085}, /* LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW */
+  {0x1e4c, 2, 1087}, /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE */
+  {0x1e4d, 2, 1089}, /* LATIN SMALL LETTER O WITH TILDE AND ACUTE */
+  {0x1e4e, 2, 1091}, /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS */
+  {0x1e4f, 2, 1093}, /* LATIN SMALL LETTER O WITH TILDE AND DIAERESIS */
+  {0x1e50, 2, 1095}, /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE */
+  {0x1e51, 2, 1097}, /* LATIN SMALL LETTER O WITH MACRON AND GRAVE */
+  {0x1e52, 2, 1099}, /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE */
+  {0x1e53, 2, 1101}, /* LATIN SMALL LETTER O WITH MACRON AND ACUTE */
+  {0x1e54, 2, 1103}, /* LATIN CAPITAL LETTER P WITH ACUTE */
+  {0x1e55, 2, 1105}, /* LATIN SMALL LETTER P WITH ACUTE */
+  {0x1e56, 2, 1107}, /* LATIN CAPITAL LETTER P WITH DOT ABOVE */
+  {0x1e57, 2, 1109}, /* LATIN SMALL LETTER P WITH DOT ABOVE */
+  {0x1e58, 2, 1111}, /* LATIN CAPITAL LETTER R WITH DOT ABOVE */
+  {0x1e59, 2, 1113}, /* LATIN SMALL LETTER R WITH DOT ABOVE */
+  {0x1e5a, 2, 1115}, /* LATIN CAPITAL LETTER R WITH DOT BELOW */
+  {0x1e5b, 2, 1117}, /* LATIN SMALL LETTER R WITH DOT BELOW */
+  {0x1e5c, 2, 1119}, /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON */
+  {0x1e5d, 2, 1121}, /* LATIN SMALL LETTER R WITH DOT BELOW AND MACRON */
+  {0x1e5e, 2, 1123}, /* LATIN CAPITAL LETTER R WITH LINE BELOW */
+  {0x1e5f, 2, 1125}, /* LATIN SMALL LETTER R WITH LINE BELOW */
+  {0x1e60, 2, 1127}, /* LATIN CAPITAL LETTER S WITH DOT ABOVE */
+  {0x1e61, 2, 1129}, /* LATIN SMALL LETTER S WITH DOT ABOVE */
+  {0x1e62, 2, 1131}, /* LATIN CAPITAL LETTER S WITH DOT BELOW */
+  {0x1e63, 2, 1133}, /* LATIN SMALL LETTER S WITH DOT BELOW */
+  {0x1e64, 2, 1135}, /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE */
+  {0x1e65, 2, 1137}, /* LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE */
+  {0x1e66, 2, 1139}, /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE */
+  {0x1e67, 2, 1141}, /* LATIN SMALL LETTER S WITH CARON AND DOT ABOVE */
+  {0x1e68, 2, 1143}, /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE */
+  {0x1e69, 2, 1145}, /* LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE */
+  {0x1e6a, 2, 1147}, /* LATIN CAPITAL LETTER T WITH DOT ABOVE */
+  {0x1e6b, 2, 1149}, /* LATIN SMALL LETTER T WITH DOT ABOVE */
+  {0x1e6c, 2, 1151}, /* LATIN CAPITAL LETTER T WITH DOT BELOW */
+  {0x1e6d, 2, 1153}, /* LATIN SMALL LETTER T WITH DOT BELOW */
+  {0x1e6e, 2, 1155}, /* LATIN CAPITAL LETTER T WITH LINE BELOW */
+  {0x1e6f, 2, 1157}, /* LATIN SMALL LETTER T WITH LINE BELOW */
+  {0x1e70, 2, 1159}, /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW */
+  {0x1e71, 2, 1161}, /* LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW */
+  {0x1e72, 2, 1163}, /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW */
+  {0x1e73, 2, 1165}, /* LATIN SMALL LETTER U WITH DIAERESIS BELOW */
+  {0x1e74, 2, 1167}, /* LATIN CAPITAL LETTER U WITH TILDE BELOW */
+  {0x1e75, 2, 1169}, /* LATIN SMALL LETTER U WITH TILDE BELOW */
+  {0x1e76, 2, 1171}, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW */
+  {0x1e77, 2, 1173}, /* LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW */
+  {0x1e78, 2, 1175}, /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE */
+  {0x1e79, 2, 1177}, /* LATIN SMALL LETTER U WITH TILDE AND ACUTE */
+  {0x1e7a, 2, 1179}, /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS */
+  {0x1e7b, 2, 1181}, /* LATIN SMALL LETTER U WITH MACRON AND DIAERESIS */
+  {0x1e7c, 2, 1183}, /* LATIN CAPITAL LETTER V WITH TILDE */
+  {0x1e7d, 2, 1185}, /* LATIN SMALL LETTER V WITH TILDE */
+  {0x1e7e, 2, 1187}, /* LATIN CAPITAL LETTER V WITH DOT BELOW */
+  {0x1e7f, 2, 1189}, /* LATIN SMALL LETTER V WITH DOT BELOW */
+  {0x1e80, 2, 1191}, /* LATIN CAPITAL LETTER W WITH GRAVE */
+  {0x1e81, 2, 1193}, /* LATIN SMALL LETTER W WITH GRAVE */
+  {0x1e82, 2, 1195}, /* LATIN CAPITAL LETTER W WITH ACUTE */
+  {0x1e83, 2, 1197}, /* LATIN SMALL LETTER W WITH ACUTE */
+  {0x1e84, 2, 1199}, /* LATIN CAPITAL LETTER W WITH DIAERESIS */
+  {0x1e85, 2, 1201}, /* LATIN SMALL LETTER W WITH DIAERESIS */
+  {0x1e86, 2, 1203}, /* LATIN CAPITAL LETTER W WITH DOT ABOVE */
+  {0x1e87, 2, 1205}, /* LATIN SMALL LETTER W WITH DOT ABOVE */
+  {0x1e88, 2, 1207}, /* LATIN CAPITAL LETTER W WITH DOT BELOW */
+  {0x1e89, 2, 1209}, /* LATIN SMALL LETTER W WITH DOT BELOW */
+  {0x1e8a, 2, 1211}, /* LATIN CAPITAL LETTER X WITH DOT ABOVE */
+  {0x1e8b, 2, 1213}, /* LATIN SMALL LETTER X WITH DOT ABOVE */
+  {0x1e8c, 2, 1215}, /* LATIN CAPITAL LETTER X WITH DIAERESIS */
+  {0x1e8d, 2, 1217}, /* LATIN SMALL LETTER X WITH DIAERESIS */
+  {0x1e8e, 2, 1219}, /* LATIN CAPITAL LETTER Y WITH DOT ABOVE */
+  {0x1e8f, 2, 1221}, /* LATIN SMALL LETTER Y WITH DOT ABOVE */
+  {0x1e90, 2, 1223}, /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX */
+  {0x1e91, 2, 1225}, /* LATIN SMALL LETTER Z WITH CIRCUMFLEX */
+  {0x1e92, 2, 1227}, /* LATIN CAPITAL LETTER Z WITH DOT BELOW */
+  {0x1e93, 2, 1229}, /* LATIN SMALL LETTER Z WITH DOT BELOW */
+  {0x1e94, 2, 1231}, /* LATIN CAPITAL LETTER Z WITH LINE BELOW */
+  {0x1e95, 2, 1233}, /* LATIN SMALL LETTER Z WITH LINE BELOW */
+  {0x1e96, 2, 1235}, /* LATIN SMALL LETTER H WITH LINE BELOW */
+  {0x1e97, 2, 1237}, /* LATIN SMALL LETTER T WITH DIAERESIS */
+  {0x1e98, 2, 1239}, /* LATIN SMALL LETTER W WITH RING ABOVE */
+  {0x1e99, 2, 1241}, /* LATIN SMALL LETTER Y WITH RING ABOVE */
+  {0x1e9a, 2, 1243}, /* LATIN SMALL LETTER A WITH RIGHT HALF RING */
+  {0x1e9b, 2, 1245}, /* LATIN SMALL LETTER LONG S WITH DOT ABOVE */
+  {0x1ea0, 2, 1247}, /* LATIN CAPITAL LETTER A WITH DOT BELOW */
+  {0x1ea1, 2, 1249}, /* LATIN SMALL LETTER A WITH DOT BELOW */
+  {0x1ea2, 2, 1251}, /* LATIN CAPITAL LETTER A WITH HOOK ABOVE */
+  {0x1ea3, 2, 1253}, /* LATIN SMALL LETTER A WITH HOOK ABOVE */
+  {0x1ea4, 2, 1255}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */
+  {0x1ea5, 2, 1257}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */
+  {0x1ea6, 2, 1259}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */
+  {0x1ea7, 2, 1261}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */
+  {0x1ea8, 2, 1263}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1ea9, 2, 1265}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1eaa, 2, 1267}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */
+  {0x1eab, 2, 1269}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */
+  {0x1eac, 2, 1271}, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1ead, 2, 1273}, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1eae, 2, 1275}, /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */
+  {0x1eaf, 2, 1277}, /* LATIN SMALL LETTER A WITH BREVE AND ACUTE */
+  {0x1eb0, 2, 1279}, /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */
+  {0x1eb1, 2, 1281}, /* LATIN SMALL LETTER A WITH BREVE AND GRAVE */
+  {0x1eb2, 2, 1283}, /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */
+  {0x1eb3, 2, 1285}, /* LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */
+  {0x1eb4, 2, 1287}, /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE */
+  {0x1eb5, 2, 1289}, /* LATIN SMALL LETTER A WITH BREVE AND TILDE */
+  {0x1eb6, 2, 1291}, /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */
+  {0x1eb7, 2, 1293}, /* LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */
+  {0x1eb8, 2, 1295}, /* LATIN CAPITAL LETTER E WITH DOT BELOW */
+  {0x1eb9, 2, 1297}, /* LATIN SMALL LETTER E WITH DOT BELOW */
+  {0x1eba, 2, 1299}, /* LATIN CAPITAL LETTER E WITH HOOK ABOVE */
+  {0x1ebb, 2, 1301}, /* LATIN SMALL LETTER E WITH HOOK ABOVE */
+  {0x1ebc, 2, 1303}, /* LATIN CAPITAL LETTER E WITH TILDE */
+  {0x1ebd, 2, 1305}, /* LATIN SMALL LETTER E WITH TILDE */
+  {0x1ebe, 2, 1307}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */
+  {0x1ebf, 2, 1309}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */
+  {0x1ec0, 2, 1311}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */
+  {0x1ec1, 2, 1313}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */
+  {0x1ec2, 2, 1315}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1ec3, 2, 1317}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1ec4, 2, 1319}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */
+  {0x1ec5, 2, 1321}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */
+  {0x1ec6, 2, 1323}, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1ec7, 2, 1325}, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1ec8, 2, 1327}, /* LATIN CAPITAL LETTER I WITH HOOK ABOVE */
+  {0x1ec9, 2, 1329}, /* LATIN SMALL LETTER I WITH HOOK ABOVE */
+  {0x1eca, 2, 1331}, /* LATIN CAPITAL LETTER I WITH DOT BELOW */
+  {0x1ecb, 2, 1333}, /* LATIN SMALL LETTER I WITH DOT BELOW */
+  {0x1ecc, 2, 1335}, /* LATIN CAPITAL LETTER O WITH DOT BELOW */
+  {0x1ecd, 2, 1337}, /* LATIN SMALL LETTER O WITH DOT BELOW */
+  {0x1ece, 2, 1339}, /* LATIN CAPITAL LETTER O WITH HOOK ABOVE */
+  {0x1ecf, 2, 1341}, /* LATIN SMALL LETTER O WITH HOOK ABOVE */
+  {0x1ed0, 2, 1343}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */
+  {0x1ed1, 2, 1345}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */
+  {0x1ed2, 2, 1347}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */
+  {0x1ed3, 2, 1349}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */
+  {0x1ed4, 2, 1351}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1ed5, 2, 1353}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */
+  {0x1ed6, 2, 1355}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */
+  {0x1ed7, 2, 1357}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */
+  {0x1ed8, 2, 1359}, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1ed9, 2, 1361}, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */
+  {0x1eda, 2, 1363}, /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE */
+  {0x1edb, 2, 1365}, /* LATIN SMALL LETTER O WITH HORN AND ACUTE */
+  {0x1edc, 2, 1367}, /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE */
+  {0x1edd, 2, 1369}, /* LATIN SMALL LETTER O WITH HORN AND GRAVE */
+  {0x1ede, 2, 1371}, /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */
+  {0x1edf, 2, 1373}, /* LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */
+  {0x1ee0, 2, 1375}, /* LATIN CAPITAL LETTER O WITH HORN AND TILDE */
+  {0x1ee1, 2, 1377}, /* LATIN SMALL LETTER O WITH HORN AND TILDE */
+  {0x1ee2, 2, 1379}, /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */
+  {0x1ee3, 2, 1381}, /* LATIN SMALL LETTER O WITH HORN AND DOT BELOW */
+  {0x1ee4, 2, 1383}, /* LATIN CAPITAL LETTER U WITH DOT BELOW */
+  {0x1ee5, 2, 1385}, /* LATIN SMALL LETTER U WITH DOT BELOW */
+  {0x1ee6, 2, 1387}, /* LATIN CAPITAL LETTER U WITH HOOK ABOVE */
+  {0x1ee7, 2, 1389}, /* LATIN SMALL LETTER U WITH HOOK ABOVE */
+  {0x1ee8, 2, 1391}, /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE */
+  {0x1ee9, 2, 1393}, /* LATIN SMALL LETTER U WITH HORN AND ACUTE */
+  {0x1eea, 2, 1395}, /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE */
+  {0x1eeb, 2, 1397}, /* LATIN SMALL LETTER U WITH HORN AND GRAVE */
+  {0x1eec, 2, 1399}, /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */
+  {0x1eed, 2, 1401}, /* LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */
+  {0x1eee, 2, 1403}, /* LATIN CAPITAL LETTER U WITH HORN AND TILDE */
+  {0x1eef, 2, 1405}, /* LATIN SMALL LETTER U WITH HORN AND TILDE */
+  {0x1ef0, 2, 1407}, /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */
+  {0x1ef1, 2, 1409}, /* LATIN SMALL LETTER U WITH HORN AND DOT BELOW */
+  {0x1ef2, 2, 1411}, /* LATIN CAPITAL LETTER Y WITH GRAVE */
+  {0x1ef3, 2, 1413}, /* LATIN SMALL LETTER Y WITH GRAVE */
+  {0x1ef4, 2, 1415}, /* LATIN CAPITAL LETTER Y WITH DOT BELOW */
+  {0x1ef5, 2, 1417}, /* LATIN SMALL LETTER Y WITH DOT BELOW */
+  {0x1ef6, 2, 1419}, /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE */
+  {0x1ef7, 2, 1421}, /* LATIN SMALL LETTER Y WITH HOOK ABOVE */
+  {0x1ef8, 2, 1423}, /* LATIN CAPITAL LETTER Y WITH TILDE */
+  {0x1ef9, 2, 1425}, /* LATIN SMALL LETTER Y WITH TILDE */
+  {0x1f00, 2, 1427}, /* GREEK SMALL LETTER ALPHA WITH PSILI */
+  {0x1f01, 2, 1429}, /* GREEK SMALL LETTER ALPHA WITH DASIA */
+  {0x1f02, 2, 1431}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA */
+  {0x1f03, 2, 1433}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA */
+  {0x1f04, 2, 1435}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA */
+  {0x1f05, 2, 1437}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA */
+  {0x1f06, 2, 1439}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI */
+  {0x1f07, 2, 1441}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI */
+  {0x1f08, 2, 1443}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI */
+  {0x1f09, 2, 1445}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA */
+  {0x1f0a, 2, 1447}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA */
+  {0x1f0b, 2, 1449}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA */
+  {0x1f0c, 2, 1451}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA */
+  {0x1f0d, 2, 1453}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA */
+  {0x1f0e, 2, 1455}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI */
+  {0x1f0f, 2, 1457}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI */
+  {0x1f10, 2, 1459}, /* GREEK SMALL LETTER EPSILON WITH PSILI */
+  {0x1f11, 2, 1461}, /* GREEK SMALL LETTER EPSILON WITH DASIA */
+  {0x1f12, 2, 1463}, /* GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA */
+  {0x1f13, 2, 1465}, /* GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA */
+  {0x1f14, 2, 1467}, /* GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA */
+  {0x1f15, 2, 1469}, /* GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA */
+  {0x1f18, 2, 1471}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI */
+  {0x1f19, 2, 1473}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA */
+  {0x1f1a, 2, 1475}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA */
+  {0x1f1b, 2, 1477}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA */
+  {0x1f1c, 2, 1479}, /* GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA */
+  {0x1f1d, 2, 1481}, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA */
+  {0x1f20, 2, 1483}, /* GREEK SMALL LETTER ETA WITH PSILI */
+  {0x1f21, 2, 1485}, /* GREEK SMALL LETTER ETA WITH DASIA */
+  {0x1f22, 2, 1487}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA */
+  {0x1f23, 2, 1489}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA */
+  {0x1f24, 2, 1491}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA */
+  {0x1f25, 2, 1493}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA */
+  {0x1f26, 2, 1495}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI */
+  {0x1f27, 2, 1497}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI */
+  {0x1f28, 2, 1499}, /* GREEK CAPITAL LETTER ETA WITH PSILI */
+  {0x1f29, 2, 1501}, /* GREEK CAPITAL LETTER ETA WITH DASIA */
+  {0x1f2a, 2, 1503}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA */
+  {0x1f2b, 2, 1505}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA */
+  {0x1f2c, 2, 1507}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA */
+  {0x1f2d, 2, 1509}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA */
+  {0x1f2e, 2, 1511}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI */
+  {0x1f2f, 2, 1513}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI */
+  {0x1f30, 2, 1515}, /* GREEK SMALL LETTER IOTA WITH PSILI */
+  {0x1f31, 2, 1517}, /* GREEK SMALL LETTER IOTA WITH DASIA */
+  {0x1f32, 2, 1519}, /* GREEK SMALL LETTER IOTA WITH PSILI AND VARIA */
+  {0x1f33, 2, 1521}, /* GREEK SMALL LETTER IOTA WITH DASIA AND VARIA */
+  {0x1f34, 2, 1523}, /* GREEK SMALL LETTER IOTA WITH PSILI AND OXIA */
+  {0x1f35, 2, 1525}, /* GREEK SMALL LETTER IOTA WITH DASIA AND OXIA */
+  {0x1f36, 2, 1527}, /* GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI */
+  {0x1f37, 2, 1529}, /* GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI */
+  {0x1f38, 2, 1531}, /* GREEK CAPITAL LETTER IOTA WITH PSILI */
+  {0x1f39, 2, 1533}, /* GREEK CAPITAL LETTER IOTA WITH DASIA */
+  {0x1f3a, 2, 1535}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA */
+  {0x1f3b, 2, 1537}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA */
+  {0x1f3c, 2, 1539}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA */
+  {0x1f3d, 2, 1541}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA */
+  {0x1f3e, 2, 1543}, /* GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI */
+  {0x1f3f, 2, 1545}, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI */
+  {0x1f40, 2, 1547}, /* GREEK SMALL LETTER OMICRON WITH PSILI */
+  {0x1f41, 2, 1549}, /* GREEK SMALL LETTER OMICRON WITH DASIA */
+  {0x1f42, 2, 1551}, /* GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA */
+  {0x1f43, 2, 1553}, /* GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA */
+  {0x1f44, 2, 1555}, /* GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA */
+  {0x1f45, 2, 1557}, /* GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA */
+  {0x1f48, 2, 1559}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI */
+  {0x1f49, 2, 1561}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA */
+  {0x1f4a, 2, 1563}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA */
+  {0x1f4b, 2, 1565}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA */
+  {0x1f4c, 2, 1567}, /* GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA */
+  {0x1f4d, 2, 1569}, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA */
+  {0x1f50, 2, 1571}, /* GREEK SMALL LETTER UPSILON WITH PSILI */
+  {0x1f51, 2, 1573}, /* GREEK SMALL LETTER UPSILON WITH DASIA */
+  {0x1f52, 2, 1575}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA */
+  {0x1f53, 2, 1577}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA */
+  {0x1f54, 2, 1579}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA */
+  {0x1f55, 2, 1581}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA */
+  {0x1f56, 2, 1583}, /* GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI */
+  {0x1f57, 2, 1585}, /* GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI */
+  {0x1f59, 2, 1587}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA */
+  {0x1f5b, 2, 1589}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA */
+  {0x1f5d, 2, 1591}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA */
+  {0x1f5f, 2, 1593}, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI */
+  {0x1f60, 2, 1595}, /* GREEK SMALL LETTER OMEGA WITH PSILI */
+  {0x1f61, 2, 1597}, /* GREEK SMALL LETTER OMEGA WITH DASIA */
+  {0x1f62, 2, 1599}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA */
+  {0x1f63, 2, 1601}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA */
+  {0x1f64, 2, 1603}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA */
+  {0x1f65, 2, 1605}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA */
+  {0x1f66, 2, 1607}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI */
+  {0x1f67, 2, 1609}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI */
+  {0x1f68, 2, 1611}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI */
+  {0x1f69, 2, 1613}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA */
+  {0x1f6a, 2, 1615}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA */
+  {0x1f6b, 2, 1617}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA */
+  {0x1f6c, 2, 1619}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA */
+  {0x1f6d, 2, 1621}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA */
+  {0x1f6e, 2, 1623}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI */
+  {0x1f6f, 2, 1625}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI */
+  {0x1f70, 2, 1627}, /* GREEK SMALL LETTER ALPHA WITH VARIA */
+  {0x1f71, 1, 1629}, /* GREEK SMALL LETTER ALPHA WITH OXIA */
+  {0x1f72, 2, 1630}, /* GREEK SMALL LETTER EPSILON WITH VARIA */
+  {0x1f73, 1, 1632}, /* GREEK SMALL LETTER EPSILON WITH OXIA */
+  {0x1f74, 2, 1633}, /* GREEK SMALL LETTER ETA WITH VARIA */
+  {0x1f75, 1, 1635}, /* GREEK SMALL LETTER ETA WITH OXIA */
+  {0x1f76, 2, 1636}, /* GREEK SMALL LETTER IOTA WITH VARIA */
+  {0x1f77, 1, 1638}, /* GREEK SMALL LETTER IOTA WITH OXIA */
+  {0x1f78, 2, 1639}, /* GREEK SMALL LETTER OMICRON WITH VARIA */
+  {0x1f79, 1, 1641}, /* GREEK SMALL LETTER OMICRON WITH OXIA */
+  {0x1f7a, 2, 1642}, /* GREEK SMALL LETTER UPSILON WITH VARIA */
+  {0x1f7b, 1, 1644}, /* GREEK SMALL LETTER UPSILON WITH OXIA */
+  {0x1f7c, 2, 1645}, /* GREEK SMALL LETTER OMEGA WITH VARIA */
+  {0x1f7d, 1, 1647}, /* GREEK SMALL LETTER OMEGA WITH OXIA */
+  {0x1f80, 2, 1648}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI */
+  {0x1f81, 2, 1650}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI */
+  {0x1f82, 2, 1652}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+  {0x1f83, 2, 1654}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+  {0x1f84, 2, 1656}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+  {0x1f85, 2, 1658}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+  {0x1f86, 2, 1660}, /* GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1f87, 2, 1662}, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1f88, 2, 1664}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI */
+  {0x1f89, 2, 1666}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI */
+  {0x1f8a, 2, 1668}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+  {0x1f8b, 2, 1670}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+  {0x1f8c, 2, 1672}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+  {0x1f8d, 2, 1674}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+  {0x1f8e, 2, 1676}, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1f8f, 2, 1678}, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1f90, 2, 1680}, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI */
+  {0x1f91, 2, 1682}, /* GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI */
+  {0x1f92, 2, 1684}, /* GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+  {0x1f93, 2, 1686}, /* GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+  {0x1f94, 2, 1688}, /* GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+  {0x1f95, 2, 1690}, /* GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+  {0x1f96, 2, 1692}, /* GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1f97, 2, 1694}, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1f98, 2, 1696}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI */
+  {0x1f99, 2, 1698}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI */
+  {0x1f9a, 2, 1700}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+  {0x1f9b, 2, 1702}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+  {0x1f9c, 2, 1704}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+  {0x1f9d, 2, 1706}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+  {0x1f9e, 2, 1708}, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1f9f, 2, 1710}, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1fa0, 2, 1712}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI */
+  {0x1fa1, 2, 1714}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI */
+  {0x1fa2, 2, 1716}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI */
+  {0x1fa3, 2, 1718}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI */
+  {0x1fa4, 2, 1720}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI */
+  {0x1fa5, 2, 1722}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI */
+  {0x1fa6, 2, 1724}, /* GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1fa7, 2, 1726}, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1fa8, 2, 1728}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI */
+  {0x1fa9, 2, 1730}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI */
+  {0x1faa, 2, 1732}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI */
+  {0x1fab, 2, 1734}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI */
+  {0x1fac, 2, 1736}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI */
+  {0x1fad, 2, 1738}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI */
+  {0x1fae, 2, 1740}, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1faf, 2, 1742}, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI */
+  {0x1fb0, 2, 1744}, /* GREEK SMALL LETTER ALPHA WITH VRACHY */
+  {0x1fb1, 2, 1746}, /* GREEK SMALL LETTER ALPHA WITH MACRON */
+  {0x1fb2, 2, 1748}, /* GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI */
+  {0x1fb3, 2, 1750}, /* GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI */
+  {0x1fb4, 2, 1752}, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI */
+  {0x1fb6, 2, 1754}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI */
+  {0x1fb7, 2, 1756}, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1fb8, 2, 1758}, /* GREEK CAPITAL LETTER ALPHA WITH VRACHY */
+  {0x1fb9, 2, 1760}, /* GREEK CAPITAL LETTER ALPHA WITH MACRON */
+  {0x1fba, 2, 1762}, /* GREEK CAPITAL LETTER ALPHA WITH VARIA */
+  {0x1fbb, 1, 1764}, /* GREEK CAPITAL LETTER ALPHA WITH OXIA */
+  {0x1fbc, 2, 1765}, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI */
+  {0x1fbd, 2, 1767}, /* GREEK KORONIS */
+  {0x1fbe, 1, 616}, /* GREEK PROSGEGRAMMENI */
+  {0x1fbf, 2, 1767}, /* GREEK PSILI */
+  {0x1fc0, 2, 1769}, /* GREEK PERISPOMENI */
+  {0x1fc1, 2, 1771}, /* GREEK DIALYTIKA AND PERISPOMENI */
+  {0x1fc2, 2, 1773}, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI */
+  {0x1fc3, 2, 1775}, /* GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI */
+  {0x1fc4, 2, 1777}, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI */
+  {0x1fc6, 2, 1779}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI */
+  {0x1fc7, 2, 1781}, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1fc8, 2, 1783}, /* GREEK CAPITAL LETTER EPSILON WITH VARIA */
+  {0x1fc9, 1, 1785}, /* GREEK CAPITAL LETTER EPSILON WITH OXIA */
+  {0x1fca, 2, 1786}, /* GREEK CAPITAL LETTER ETA WITH VARIA */
+  {0x1fcb, 1, 1788}, /* GREEK CAPITAL LETTER ETA WITH OXIA */
+  {0x1fcc, 2, 1789}, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI */
+  {0x1fcd, 2, 1791}, /* GREEK PSILI AND VARIA */
+  {0x1fce, 2, 1793}, /* GREEK PSILI AND OXIA */
+  {0x1fcf, 2, 1795}, /* GREEK PSILI AND PERISPOMENI */
+  {0x1fd0, 2, 1797}, /* GREEK SMALL LETTER IOTA WITH VRACHY */
+  {0x1fd1, 2, 1799}, /* GREEK SMALL LETTER IOTA WITH MACRON */
+  {0x1fd2, 2, 1801}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA */
+  {0x1fd3, 1, 1803}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA */
+  {0x1fd6, 2, 1804}, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI */
+  {0x1fd7, 2, 1806}, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI */
+  {0x1fd8, 2, 1808}, /* GREEK CAPITAL LETTER IOTA WITH VRACHY */
+  {0x1fd9, 2, 1810}, /* GREEK CAPITAL LETTER IOTA WITH MACRON */
+  {0x1fda, 2, 1812}, /* GREEK CAPITAL LETTER IOTA WITH VARIA */
+  {0x1fdb, 1, 1814}, /* GREEK CAPITAL LETTER IOTA WITH OXIA */
+  {0x1fdd, 2, 1815}, /* GREEK DASIA AND VARIA */
+  {0x1fde, 2, 1817}, /* GREEK DASIA AND OXIA */
+  {0x1fdf, 2, 1819}, /* GREEK DASIA AND PERISPOMENI */
+  {0x1fe0, 2, 1821}, /* GREEK SMALL LETTER UPSILON WITH VRACHY */
+  {0x1fe1, 2, 1823}, /* GREEK SMALL LETTER UPSILON WITH MACRON */
+  {0x1fe2, 2, 1825}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA */
+  {0x1fe3, 1, 1827}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA */
+  {0x1fe4, 2, 1828}, /* GREEK SMALL LETTER RHO WITH PSILI */
+  {0x1fe5, 2, 1830}, /* GREEK SMALL LETTER RHO WITH DASIA */
+  {0x1fe6, 2, 1832}, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI */
+  {0x1fe7, 2, 1834}, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI */
+  {0x1fe8, 2, 1836}, /* GREEK CAPITAL LETTER UPSILON WITH VRACHY */
+  {0x1fe9, 2, 1838}, /* GREEK CAPITAL LETTER UPSILON WITH MACRON */
+  {0x1fea, 2, 1840}, /* GREEK CAPITAL LETTER UPSILON WITH VARIA */
+  {0x1feb, 1, 1842}, /* GREEK CAPITAL LETTER UPSILON WITH OXIA */
+  {0x1fec, 2, 1843}, /* GREEK CAPITAL LETTER RHO WITH DASIA */
+  {0x1fed, 2, 1845}, /* GREEK DIALYTIKA AND VARIA */
+  {0x1fee, 1, 1847}, /* GREEK DIALYTIKA AND OXIA */
+  {0x1fef, 1, 1848}, /* GREEK VARIA */
+  {0x1ff2, 2, 1849}, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI */
+  {0x1ff3, 2, 1851}, /* GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI */
+  {0x1ff4, 2, 1853}, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI */
+  {0x1ff6, 2, 1855}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI */
+  {0x1ff7, 2, 1857}, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI */
+  {0x1ff8, 2, 1859}, /* GREEK CAPITAL LETTER OMICRON WITH VARIA */
+  {0x1ff9, 1, 1861}, /* GREEK CAPITAL LETTER OMICRON WITH OXIA */
+  {0x1ffa, 2, 1862}, /* GREEK CAPITAL LETTER OMEGA WITH VARIA */
+  {0x1ffb, 1, 1864}, /* GREEK CAPITAL LETTER OMEGA WITH OXIA */
+  {0x1ffc, 2, 1865}, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI */
+  {0x1ffd, 1, 1867}, /* GREEK OXIA */
+  {0x1ffe, 2, 1868}, /* GREEK DASIA */
+  {0x2000, 1, 1870}, /* EN QUAD */
+  {0x2001, 1, 1871}, /* EM QUAD */
+  {0x2002, 1, 1872}, /* EN SPACE */
+  {0x2003, 1, 1873}, /* EM SPACE */
+  {0x2004, 1, 1874}, /* THREE-PER-EM SPACE */
+  {0x2005, 1, 1875}, /* FOUR-PER-EM SPACE */
+  {0x2006, 1, 1876}, /* SIX-PER-EM SPACE */
+  {0x2007, 1, 1877}, /* FIGURE SPACE */
+  {0x2008, 1, 1878}, /* PUNCTUATION SPACE */
+  {0x2009, 1, 1879}, /* THIN SPACE */
+  {0x200a, 1, 1880}, /* HAIR SPACE */
+  {0x2011, 1, 1881}, /* NON-BREAKING HYPHEN */
+  {0x2017, 2, 1882}, /* DOUBLE LOW LINE */
+  {0x2024, 1, 1884}, /* ONE DOT LEADER */
+  {0x2025, 2, 1885}, /* TWO DOT LEADER */
+  {0x2026, 3, 1884}, /* HORIZONTAL ELLIPSIS */
+  {0x202f, 1, 1887}, /* NARROW NO-BREAK SPACE */
+  {0x2033, 2, 1888}, /* DOUBLE PRIME */
+  {0x2034, 3, 1890}, /* TRIPLE PRIME */
+  {0x2036, 2, 1893}, /* REVERSED DOUBLE PRIME */
+  {0x2037, 3, 1895}, /* REVERSED TRIPLE PRIME */
+  {0x203c, 2, 1898}, /* DOUBLE EXCLAMATION MARK */
+  {0x203e, 2, 1900}, /* OVERLINE */
+  {0x2047, 2, 1902}, /* DOUBLE QUESTION MARK */
+  {0x2048, 2, 1904}, /* QUESTION EXCLAMATION MARK */
+  {0x2049, 2, 1906}, /* EXCLAMATION QUESTION MARK */
+  {0x2057, 4, 1888}, /* QUADRUPLE PRIME */
+  {0x205f, 1, 1908}, /* MEDIUM MATHEMATICAL SPACE */
+  {0x2070, 1, 1909}, /* SUPERSCRIPT ZERO */
+  {0x2071, 1, 98}, /* SUPERSCRIPT LATIN SMALL LETTER I */
+  {0x2074, 1, 17}, /* SUPERSCRIPT FOUR */
+  {0x2075, 1, 1910}, /* SUPERSCRIPT FIVE */
+  {0x2076, 1, 1911}, /* SUPERSCRIPT SIX */
+  {0x2077, 1, 1912}, /* SUPERSCRIPT SEVEN */
+  {0x2078, 1, 1913}, /* SUPERSCRIPT EIGHT */
+  {0x2079, 1, 1914}, /* SUPERSCRIPT NINE */
+  {0x207a, 1, 1915}, /* SUPERSCRIPT PLUS SIGN */
+  {0x207b, 1, 1916}, /* SUPERSCRIPT MINUS */
+  {0x207c, 1, 1917}, /* SUPERSCRIPT EQUALS SIGN */
+  {0x207d, 1, 1918}, /* SUPERSCRIPT LEFT PARENTHESIS */
+  {0x207e, 1, 1919}, /* SUPERSCRIPT RIGHT PARENTHESIS */
+  {0x207f, 1, 106}, /* SUPERSCRIPT LATIN SMALL LETTER N */
+  {0x2080, 1, 1909}, /* SUBSCRIPT ZERO */
+  {0x2081, 1, 13}, /* SUBSCRIPT ONE */
+  {0x2082, 1, 6}, /* SUBSCRIPT TWO */
+  {0x2083, 1, 7}, /* SUBSCRIPT THREE */
+  {0x2084, 1, 17}, /* SUBSCRIPT FOUR */
+  {0x2085, 1, 1910}, /* SUBSCRIPT FIVE */
+  {0x2086, 1, 1911}, /* SUBSCRIPT SIX */
+  {0x2087, 1, 1912}, /* SUBSCRIPT SEVEN */
+  {0x2088, 1, 1913}, /* SUBSCRIPT EIGHT */
+  {0x2089, 1, 1914}, /* SUBSCRIPT NINE */
+  {0x208a, 1, 1915}, /* SUBSCRIPT PLUS SIGN */
+  {0x208b, 1, 1916}, /* SUBSCRIPT MINUS */
+  {0x208c, 1, 1917}, /* SUBSCRIPT EQUALS SIGN */
+  {0x208d, 1, 1918}, /* SUBSCRIPT LEFT PARENTHESIS */
+  {0x208e, 1, 1919}, /* SUBSCRIPT RIGHT PARENTHESIS */
+  {0x20a8, 2, 1920}, /* RUPEE SIGN */
+  {0x2100, 3, 1922}, /* ACCOUNT OF */
+  {0x2101, 3, 1925}, /* ADDRESSED TO THE SUBJECT */
+  {0x2102, 1, 36}, /* DOUBLE-STRUCK CAPITAL C */
+  {0x2103, 2, 1928}, /* DEGREE CELSIUS */
+  {0x2105, 3, 1930}, /* CARE OF */
+  {0x2106, 3, 1933}, /* CADA UNA */
+  {0x2107, 1, 1936}, /* EULER CONSTANT */
+  {0x2109, 2, 1937}, /* DEGREE FAHRENHEIT */
+  {0x210a, 1, 184}, /* SCRIPT SMALL G */
+  {0x210b, 1, 198}, /* SCRIPT CAPITAL H */
+  {0x210c, 1, 198}, /* BLACK-LETTER CAPITAL H */
+  {0x210d, 1, 198}, /* DOUBLE-STRUCK CAPITAL H */
+  {0x210e, 1, 200}, /* PLANCK CONSTANT */
+  {0x210f, 1, 1939}, /* PLANCK CONSTANT OVER TWO PI */
+  {0x2110, 1, 46}, /* SCRIPT CAPITAL I */
+  {0x2111, 1, 46}, /* BLACK-LETTER CAPITAL I */
+  {0x2112, 1, 232}, /* SCRIPT CAPITAL L */
+  {0x2113, 1, 234}, /* SCRIPT SMALL L */
+  {0x2115, 1, 54}, /* DOUBLE-STRUCK CAPITAL N */
+  {0x2116, 2, 1940}, /* NUMERO SIGN */
+  {0x2119, 1, 914}, /* DOUBLE-STRUCK CAPITAL P */
+  {0x211a, 1, 1942}, /* DOUBLE-STRUCK CAPITAL Q */
+  {0x211b, 1, 274}, /* SCRIPT CAPITAL R */
+  {0x211c, 1, 274}, /* BLACK-LETTER CAPITAL R */
+  {0x211d, 1, 274}, /* DOUBLE-STRUCK CAPITAL R */
+  {0x2120, 2, 1943}, /* SERVICE MARK */
+  {0x2121, 3, 1945}, /* TELEPHONE SIGN */
+  {0x2122, 2, 1948}, /* TRADE MARK SIGN */
+  {0x2124, 1, 344}, /* DOUBLE-STRUCK CAPITAL Z */
+  {0x2126, 1, 602}, /* OHM SIGN */
+  {0x2128, 1, 344}, /* BLACK-LETTER CAPITAL Z */
+  {0x212a, 1, 228}, /* KELVIN SIGN */
+  {0x212b, 1, 462}, /* ANGSTROM SIGN */
+  {0x212c, 1, 910}, /* SCRIPT CAPITAL B */
+  {0x212d, 1, 36}, /* BLACK-LETTER CAPITAL C */
+  {0x212f, 1, 90}, /* SCRIPT SMALL E */
+  {0x2130, 1, 38}, /* SCRIPT CAPITAL E */
+  {0x2131, 1, 995}, /* SCRIPT CAPITAL F */
+  {0x2133, 1, 912}, /* SCRIPT CAPITAL M */
+  {0x2134, 1, 14}, /* SCRIPT SMALL O */
+  {0x2135, 1, 1950}, /* ALEF SYMBOL */
+  {0x2136, 1, 1951}, /* BET SYMBOL */
+  {0x2137, 1, 1952}, /* GIMEL SYMBOL */
+  {0x2138, 1, 1953}, /* DALET SYMBOL */
+  {0x2139, 1, 98}, /* INFORMATION SOURCE */
+  {0x213b, 3, 1954}, /* FACSIMILE SIGN */
+  {0x213d, 1, 932}, /* DOUBLE-STRUCK SMALL GAMMA */
+  {0x213e, 1, 1957}, /* DOUBLE-STRUCK CAPITAL GAMMA */
+  {0x213f, 1, 1958}, /* DOUBLE-STRUCK CAPITAL PI */
+  {0x2140, 1, 1959}, /* DOUBLE-STRUCK N-ARY SUMMATION */
+  {0x2145, 1, 158}, /* DOUBLE-STRUCK ITALIC CAPITAL D */
+  {0x2146, 1, 160}, /* DOUBLE-STRUCK ITALIC SMALL D */
+  {0x2147, 1, 90}, /* DOUBLE-STRUCK ITALIC SMALL E */
+  {0x2148, 1, 98}, /* DOUBLE-STRUCK ITALIC SMALL I */
+  {0x2149, 1, 223}, /* DOUBLE-STRUCK ITALIC SMALL J */
+  {0x2153, 3, 1960}, /* VULGAR FRACTION ONE THIRD */
+  {0x2154, 3, 1963}, /* VULGAR FRACTION TWO THIRDS */
+  {0x2155, 3, 1966}, /* VULGAR FRACTION ONE FIFTH */
+  {0x2156, 3, 1969}, /* VULGAR FRACTION TWO FIFTHS */
+  {0x2157, 3, 1972}, /* VULGAR FRACTION THREE FIFTHS */
+  {0x2158, 3, 1975}, /* VULGAR FRACTION FOUR FIFTHS */
+  {0x2159, 3, 1978}, /* VULGAR FRACTION ONE SIXTH */
+  {0x215a, 3, 1981}, /* VULGAR FRACTION FIVE SIXTHS */
+  {0x215b, 3, 1984}, /* VULGAR FRACTION ONE EIGHTH */
+  {0x215c, 3, 1987}, /* VULGAR FRACTION THREE EIGHTHS */
+  {0x215d, 3, 1990}, /* VULGAR FRACTION FIVE EIGHTHS */
+  {0x215e, 3, 1993}, /* VULGAR FRACTION SEVEN EIGHTHS */
+  {0x215f, 2, 15}, /* FRACTION NUMERATOR ONE */
+  {0x2160, 1, 46}, /* ROMAN NUMERAL ONE */
+  {0x2161, 2, 1996}, /* ROMAN NUMERAL TWO */
+  {0x2162, 3, 1998}, /* ROMAN NUMERAL THREE */
+  {0x2163, 2, 2001}, /* ROMAN NUMERAL FOUR */
+  {0x2164, 1, 1183}, /* ROMAN NUMERAL FIVE */
+  {0x2165, 2, 2003}, /* ROMAN NUMERAL SIX */
+  {0x2166, 3, 2005}, /* ROMAN NUMERAL SEVEN */
+  {0x2167, 4, 2008}, /* ROMAN NUMERAL EIGHT */
+  {0x2168, 2, 2012}, /* ROMAN NUMERAL NINE */
+  {0x2169, 1, 1211}, /* ROMAN NUMERAL TEN */
+  {0x216a, 2, 2014}, /* ROMAN NUMERAL ELEVEN */
+  {0x216b, 3, 2016}, /* ROMAN NUMERAL TWELVE */
+  {0x216c, 1, 232}, /* ROMAN NUMERAL FIFTY */
+  {0x216d, 1, 36}, /* ROMAN NUMERAL ONE HUNDRED */
+  {0x216e, 1, 158}, /* ROMAN NUMERAL FIVE HUNDRED */
+  {0x216f, 1, 912}, /* ROMAN NUMERAL ONE THOUSAND */
+  {0x2170, 1, 98}, /* SMALL ROMAN NUMERAL ONE */
+  {0x2171, 2, 2019}, /* SMALL ROMAN NUMERAL TWO */
+  {0x2172, 3, 2021}, /* SMALL ROMAN NUMERAL THREE */
+  {0x2173, 2, 2024}, /* SMALL ROMAN NUMERAL FOUR */
+  {0x2174, 1, 930}, /* SMALL ROMAN NUMERAL FIVE */
+  {0x2175, 2, 2026}, /* SMALL ROMAN NUMERAL SIX */
+  {0x2176, 3, 2028}, /* SMALL ROMAN NUMERAL SEVEN */
+  {0x2177, 4, 2031}, /* SMALL ROMAN NUMERAL EIGHT */
+  {0x2178, 2, 2035}, /* SMALL ROMAN NUMERAL NINE */
+  {0x2179, 1, 579}, /* SMALL ROMAN NUMERAL TEN */
+  {0x217a, 2, 2037}, /* SMALL ROMAN NUMERAL ELEVEN */
+  {0x217b, 3, 2039}, /* SMALL ROMAN NUMERAL TWELVE */
+  {0x217c, 1, 234}, /* SMALL ROMAN NUMERAL FIFTY */
+  {0x217d, 1, 88}, /* SMALL ROMAN NUMERAL ONE HUNDRED */
+  {0x217e, 1, 160}, /* SMALL ROMAN NUMERAL FIVE HUNDRED */
+  {0x217f, 1, 922}, /* SMALL ROMAN NUMERAL ONE THOUSAND */
+  {0x219a, 2, 2042}, /* LEFTWARDS ARROW WITH STROKE */
+  {0x219b, 2, 2044}, /* RIGHTWARDS ARROW WITH STROKE */
+  {0x21ae, 2, 2046}, /* LEFT RIGHT ARROW WITH STROKE */
+  {0x21cd, 2, 2048}, /* LEFTWARDS DOUBLE ARROW WITH STROKE */
+  {0x21ce, 2, 2050}, /* LEFT RIGHT DOUBLE ARROW WITH STROKE */
+  {0x21cf, 2, 2052}, /* RIGHTWARDS DOUBLE ARROW WITH STROKE */
+  {0x2204, 2, 2054}, /* THERE DOES NOT EXIST */
+  {0x2209, 2, 2056}, /* NOT AN ELEMENT OF */
+  {0x220c, 2, 2058}, /* DOES NOT CONTAIN AS MEMBER */
+  {0x2224, 2, 2060}, /* DOES NOT DIVIDE */
+  {0x2226, 2, 2062}, /* NOT PARALLEL TO */
+  {0x222c, 2, 2064}, /* DOUBLE INTEGRAL */
+  {0x222d, 3, 2066}, /* TRIPLE INTEGRAL */
+  {0x222f, 2, 2069}, /* SURFACE INTEGRAL */
+  {0x2230, 3, 2071}, /* VOLUME INTEGRAL */
+  {0x2241, 2, 2074}, /* NOT TILDE */
+  {0x2244, 2, 2076}, /* NOT ASYMPTOTICALLY EQUAL TO */
+  {0x2247, 2, 2078}, /* NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO */
+  {0x2249, 2, 2080}, /* NOT ALMOST EQUAL TO */
+  {0x2260, 2, 2082}, /* NOT EQUAL TO */
+  {0x2262, 2, 2084}, /* NOT IDENTICAL TO */
+  {0x226d, 2, 2086}, /* NOT EQUIVALENT TO */
+  {0x226e, 2, 2088}, /* NOT LESS-THAN */
+  {0x226f, 2, 2090}, /* NOT GREATER-THAN */
+  {0x2270, 2, 2092}, /* NEITHER LESS-THAN NOR EQUAL TO */
+  {0x2271, 2, 2094}, /* NEITHER GREATER-THAN NOR EQUAL TO */
+  {0x2274, 2, 2096}, /* NEITHER LESS-THAN NOR EQUIVALENT TO */
+  {0x2275, 2, 2098}, /* NEITHER GREATER-THAN NOR EQUIVALENT TO */
+  {0x2278, 2, 2100}, /* NEITHER LESS-THAN NOR GREATER-THAN */
+  {0x2279, 2, 2102}, /* NEITHER GREATER-THAN NOR LESS-THAN */
+  {0x2280, 2, 2104}, /* DOES NOT PRECEDE */
+  {0x2281, 2, 2106}, /* DOES NOT SUCCEED */
+  {0x2284, 2, 2108}, /* NOT A SUBSET OF */
+  {0x2285, 2, 2110}, /* NOT A SUPERSET OF */
+  {0x2288, 2, 2112}, /* NEITHER A SUBSET OF NOR EQUAL TO */
+  {0x2289, 2, 2114}, /* NEITHER A SUPERSET OF NOR EQUAL TO */
+  {0x22ac, 2, 2116}, /* DOES NOT PROVE */
+  {0x22ad, 2, 2118}, /* NOT TRUE */
+  {0x22ae, 2, 2120}, /* DOES NOT FORCE */
+  {0x22af, 2, 2122}, /* NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE */
+  {0x22e0, 2, 2124}, /* DOES NOT PRECEDE OR EQUAL */
+  {0x22e1, 2, 2126}, /* DOES NOT SUCCEED OR EQUAL */
+  {0x22e2, 2, 2128}, /* NOT SQUARE IMAGE OF OR EQUAL TO */
+  {0x22e3, 2, 2130}, /* NOT SQUARE ORIGINAL OF OR EQUAL TO */
+  {0x22ea, 2, 2132}, /* NOT NORMAL SUBGROUP OF */
+  {0x22eb, 2, 2134}, /* DOES NOT CONTAIN AS NORMAL SUBGROUP */
+  {0x22ec, 2, 2136}, /* NOT NORMAL SUBGROUP OF OR EQUAL TO */
+  {0x22ed, 2, 2138}, /* DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL */
+  {0x2329, 1, 2140}, /* LEFT-POINTING ANGLE BRACKET */
+  {0x232a, 1, 2141}, /* RIGHT-POINTING ANGLE BRACKET */
+  {0x2460, 1, 13}, /* CIRCLED DIGIT ONE */
+  {0x2461, 1, 6}, /* CIRCLED DIGIT TWO */
+  {0x2462, 1, 7}, /* CIRCLED DIGIT THREE */
+  {0x2463, 1, 17}, /* CIRCLED DIGIT FOUR */
+  {0x2464, 1, 1910}, /* CIRCLED DIGIT FIVE */
+  {0x2465, 1, 1911}, /* CIRCLED DIGIT SIX */
+  {0x2466, 1, 1912}, /* CIRCLED DIGIT SEVEN */
+  {0x2467, 1, 1913}, /* CIRCLED DIGIT EIGHT */
+  {0x2468, 1, 1914}, /* CIRCLED DIGIT NINE */
+  {0x2469, 2, 2142}, /* CIRCLED NUMBER TEN */
+  {0x246a, 2, 2144}, /* CIRCLED NUMBER ELEVEN */
+  {0x246b, 2, 2146}, /* CIRCLED NUMBER TWELVE */
+  {0x246c, 2, 2148}, /* CIRCLED NUMBER THIRTEEN */
+  {0x246d, 2, 2150}, /* CIRCLED NUMBER FOURTEEN */
+  {0x246e, 2, 2152}, /* CIRCLED NUMBER FIFTEEN */
+  {0x246f, 2, 2154}, /* CIRCLED NUMBER SIXTEEN */
+  {0x2470, 2, 2156}, /* CIRCLED NUMBER SEVENTEEN */
+  {0x2471, 2, 2158}, /* CIRCLED NUMBER EIGHTEEN */
+  {0x2472, 2, 2160}, /* CIRCLED NUMBER NINETEEN */
+  {0x2473, 2, 2162}, /* CIRCLED NUMBER TWENTY */
+  {0x2474, 3, 2164}, /* PARENTHESIZED DIGIT ONE */
+  {0x2475, 3, 2167}, /* PARENTHESIZED DIGIT TWO */
+  {0x2476, 3, 2170}, /* PARENTHESIZED DIGIT THREE */
+  {0x2477, 3, 2173}, /* PARENTHESIZED DIGIT FOUR */
+  {0x2478, 3, 2176}, /* PARENTHESIZED DIGIT FIVE */
+  {0x2479, 3, 2179}, /* PARENTHESIZED DIGIT SIX */
+  {0x247a, 3, 2182}, /* PARENTHESIZED DIGIT SEVEN */
+  {0x247b, 3, 2185}, /* PARENTHESIZED DIGIT EIGHT */
+  {0x247c, 3, 2188}, /* PARENTHESIZED DIGIT NINE */
+  {0x247d, 4, 2191}, /* PARENTHESIZED NUMBER TEN */
+  {0x247e, 4, 2195}, /* PARENTHESIZED NUMBER ELEVEN */
+  {0x247f, 4, 2199}, /* PARENTHESIZED NUMBER TWELVE */
+  {0x2480, 4, 2203}, /* PARENTHESIZED NUMBER THIRTEEN */
+  {0x2481, 4, 2207}, /* PARENTHESIZED NUMBER FOURTEEN */
+  {0x2482, 4, 2211}, /* PARENTHESIZED NUMBER FIFTEEN */
+  {0x2483, 4, 2215}, /* PARENTHESIZED NUMBER SIXTEEN */
+  {0x2484, 4, 2219}, /* PARENTHESIZED NUMBER SEVENTEEN */
+  {0x2485, 4, 2223}, /* PARENTHESIZED NUMBER EIGHTEEN */
+  {0x2486, 4, 2227}, /* PARENTHESIZED NUMBER NINETEEN */
+  {0x2487, 4, 2231}, /* PARENTHESIZED NUMBER TWENTY */
+  {0x2488, 2, 2235}, /* DIGIT ONE FULL STOP */
+  {0x2489, 2, 2237}, /* DIGIT TWO FULL STOP */
+  {0x248a, 2, 2239}, /* DIGIT THREE FULL STOP */
+  {0x248b, 2, 2241}, /* DIGIT FOUR FULL STOP */
+  {0x248c, 2, 2243}, /* DIGIT FIVE FULL STOP */
+  {0x248d, 2, 2245}, /* DIGIT SIX FULL STOP */
+  {0x248e, 2, 2247}, /* DIGIT SEVEN FULL STOP */
+  {0x248f, 2, 2249}, /* DIGIT EIGHT FULL STOP */
+  {0x2490, 2, 2251}, /* DIGIT NINE FULL STOP */
+  {0x2491, 3, 2253}, /* NUMBER TEN FULL STOP */
+  {0x2492, 3, 2256}, /* NUMBER ELEVEN FULL STOP */
+  {0x2493, 3, 2259}, /* NUMBER TWELVE FULL STOP */
+  {0x2494, 3, 2262}, /* NUMBER THIRTEEN FULL STOP */
+  {0x2495, 3, 2265}, /* NUMBER FOURTEEN FULL STOP */
+  {0x2496, 3, 2268}, /* NUMBER FIFTEEN FULL STOP */
+  {0x2497, 3, 2271}, /* NUMBER SIXTEEN FULL STOP */
+  {0x2498, 3, 2274}, /* NUMBER SEVENTEEN FULL STOP */
+  {0x2499, 3, 2277}, /* NUMBER EIGHTEEN FULL STOP */
+  {0x249a, 3, 2280}, /* NUMBER NINETEEN FULL STOP */
+  {0x249b, 3, 2283}, /* NUMBER TWENTY FULL STOP */
+  {0x249c, 3, 2286}, /* PARENTHESIZED LATIN SMALL LETTER A */
+  {0x249d, 3, 2289}, /* PARENTHESIZED LATIN SMALL LETTER B */
+  {0x249e, 3, 2292}, /* PARENTHESIZED LATIN SMALL LETTER C */
+  {0x249f, 3, 2295}, /* PARENTHESIZED LATIN SMALL LETTER D */
+  {0x24a0, 3, 2298}, /* PARENTHESIZED LATIN SMALL LETTER E */
+  {0x24a1, 3, 2301}, /* PARENTHESIZED LATIN SMALL LETTER F */
+  {0x24a2, 3, 2304}, /* PARENTHESIZED LATIN SMALL LETTER G */
+  {0x24a3, 3, 2307}, /* PARENTHESIZED LATIN SMALL LETTER H */
+  {0x24a4, 3, 2310}, /* PARENTHESIZED LATIN SMALL LETTER I */
+  {0x24a5, 3, 2313}, /* PARENTHESIZED LATIN SMALL LETTER J */
+  {0x24a6, 3, 2316}, /* PARENTHESIZED LATIN SMALL LETTER K */
+  {0x24a7, 3, 2319}, /* PARENTHESIZED LATIN SMALL LETTER L */
+  {0x24a8, 3, 2322}, /* PARENTHESIZED LATIN SMALL LETTER M */
+  {0x24a9, 3, 2325}, /* PARENTHESIZED LATIN SMALL LETTER N */
+  {0x24aa, 3, 2328}, /* PARENTHESIZED LATIN SMALL LETTER O */
+  {0x24ab, 3, 2331}, /* PARENTHESIZED LATIN SMALL LETTER P */
+  {0x24ac, 3, 2334}, /* PARENTHESIZED LATIN SMALL LETTER Q */
+  {0x24ad, 3, 2337}, /* PARENTHESIZED LATIN SMALL LETTER R */
+  {0x24ae, 3, 2340}, /* PARENTHESIZED LATIN SMALL LETTER S */
+  {0x24af, 3, 2343}, /* PARENTHESIZED LATIN SMALL LETTER T */
+  {0x24b0, 3, 2346}, /* PARENTHESIZED LATIN SMALL LETTER U */
+  {0x24b1, 3, 2349}, /* PARENTHESIZED LATIN SMALL LETTER V */
+  {0x24b2, 3, 2352}, /* PARENTHESIZED LATIN SMALL LETTER W */
+  {0x24b3, 3, 2355}, /* PARENTHESIZED LATIN SMALL LETTER X */
+  {0x24b4, 3, 2358}, /* PARENTHESIZED LATIN SMALL LETTER Y */
+  {0x24b5, 3, 2361}, /* PARENTHESIZED LATIN SMALL LETTER Z */
+  {0x24b6, 1, 24}, /* CIRCLED LATIN CAPITAL LETTER A */
+  {0x24b7, 1, 910}, /* CIRCLED LATIN CAPITAL LETTER B */
+  {0x24b8, 1, 36}, /* CIRCLED LATIN CAPITAL LETTER C */
+  {0x24b9, 1, 158}, /* CIRCLED LATIN CAPITAL LETTER D */
+  {0x24ba, 1, 38}, /* CIRCLED LATIN CAPITAL LETTER E */
+  {0x24bb, 1, 995}, /* CIRCLED LATIN CAPITAL LETTER F */
+  {0x24bc, 1, 182}, /* CIRCLED LATIN CAPITAL LETTER G */
+  {0x24bd, 1, 198}, /* CIRCLED LATIN CAPITAL LETTER H */
+  {0x24be, 1, 46}, /* CIRCLED LATIN CAPITAL LETTER I */
+  {0x24bf, 1, 221}, /* CIRCLED LATIN CAPITAL LETTER J */
+  {0x24c0, 1, 228}, /* CIRCLED LATIN CAPITAL LETTER K */
+  {0x24c1, 1, 232}, /* CIRCLED LATIN CAPITAL LETTER L */
+  {0x24c2, 1, 912}, /* CIRCLED LATIN CAPITAL LETTER M */
+  {0x24c3, 1, 54}, /* CIRCLED LATIN CAPITAL LETTER N */
+  {0x24c4, 1, 56}, /* CIRCLED LATIN CAPITAL LETTER O */
+  {0x24c5, 1, 914}, /* CIRCLED LATIN CAPITAL LETTER P */
+  {0x24c6, 1, 1942}, /* CIRCLED LATIN CAPITAL LETTER Q */
+  {0x24c7, 1, 274}, /* CIRCLED LATIN CAPITAL LETTER R */
+  {0x24c8, 1, 286}, /* CIRCLED LATIN CAPITAL LETTER S */
+  {0x24c9, 1, 302}, /* CIRCLED LATIN CAPITAL LETTER T */
+  {0x24ca, 1, 66}, /* CIRCLED LATIN CAPITAL LETTER U */
+  {0x24cb, 1, 1183}, /* CIRCLED LATIN CAPITAL LETTER V */
+  {0x24cc, 1, 334}, /* CIRCLED LATIN CAPITAL LETTER W */
+  {0x24cd, 1, 1211}, /* CIRCLED LATIN CAPITAL LETTER X */
+  {0x24ce, 1, 74}, /* CIRCLED LATIN CAPITAL LETTER Y */
+  {0x24cf, 1, 344}, /* CIRCLED LATIN CAPITAL LETTER Z */
+  {0x24d0, 1, 3}, /* CIRCLED LATIN SMALL LETTER A */
+  {0x24d1, 1, 918}, /* CIRCLED LATIN SMALL LETTER B */
+  {0x24d2, 1, 88}, /* CIRCLED LATIN SMALL LETTER C */
+  {0x24d3, 1, 160}, /* CIRCLED LATIN SMALL LETTER D */
+  {0x24d4, 1, 90}, /* CIRCLED LATIN SMALL LETTER E */
+  {0x24d5, 1, 997}, /* CIRCLED LATIN SMALL LETTER F */
+  {0x24d6, 1, 184}, /* CIRCLED LATIN SMALL LETTER G */
+  {0x24d7, 1, 200}, /* CIRCLED LATIN SMALL LETTER H */
+  {0x24d8, 1, 98}, /* CIRCLED LATIN SMALL LETTER I */
+  {0x24d9, 1, 223}, /* CIRCLED LATIN SMALL LETTER J */
+  {0x24da, 1, 230}, /* CIRCLED LATIN SMALL LETTER K */
+  {0x24db, 1, 234}, /* CIRCLED LATIN SMALL LETTER L */
+  {0x24dc, 1, 922}, /* CIRCLED LATIN SMALL LETTER M */
+  {0x24dd, 1, 106}, /* CIRCLED LATIN SMALL LETTER N */
+  {0x24de, 1, 14}, /* CIRCLED LATIN SMALL LETTER O */
+  {0x24df, 1, 927}, /* CIRCLED LATIN SMALL LETTER P */
+  {0x24e0, 1, 2335}, /* CIRCLED LATIN SMALL LETTER Q */
+  {0x24e1, 1, 276}, /* CIRCLED LATIN SMALL LETTER R */
+  {0x24e2, 1, 288}, /* CIRCLED LATIN SMALL LETTER S */
+  {0x24e3, 1, 304}, /* CIRCLED LATIN SMALL LETTER T */
+  {0x24e4, 1, 118}, /* CIRCLED LATIN SMALL LETTER U */
+  {0x24e5, 1, 930}, /* CIRCLED LATIN SMALL LETTER V */
+  {0x24e6, 1, 336}, /* CIRCLED LATIN SMALL LETTER W */
+  {0x24e7, 1, 579}, /* CIRCLED LATIN SMALL LETTER X */
+  {0x24e8, 1, 126}, /* CIRCLED LATIN SMALL LETTER Y */
+  {0x24e9, 1, 346}, /* CIRCLED LATIN SMALL LETTER Z */
+  {0x24ea, 1, 1909}, /* CIRCLED DIGIT ZERO */
+  {0x2a0c, 4, 2064}, /* QUADRUPLE INTEGRAL OPERATOR */
+  {0x2a74, 3, 2364}, /* DOUBLE COLON EQUAL */
+  {0x2a75, 2, 2367}, /* TWO CONSECUTIVE EQUALS SIGNS */
+  {0x2a76, 3, 2366}, /* THREE CONSECUTIVE EQUALS SIGNS */
+  {0x2adc, 2, 2369}, /* FORKING */
+  {0x2e9f, 1, 2371}, /* CJK RADICAL MOTHER */
+  {0x2ef3, 1, 2372}, /* CJK RADICAL C-SIMPLIFIED TURTLE */
+  {0x2f00, 1, 2373}, /* KANGXI RADICAL ONE */
+  {0x2f01, 1, 2374}, /* KANGXI RADICAL LINE */
+  {0x2f02, 1, 2375}, /* KANGXI RADICAL DOT */
+  {0x2f03, 1, 2376}, /* KANGXI RADICAL SLASH */
+  {0x2f04, 1, 2377}, /* KANGXI RADICAL SECOND */
+  {0x2f05, 1, 2378}, /* KANGXI RADICAL HOOK */
+  {0x2f06, 1, 2379}, /* KANGXI RADICAL TWO */
+  {0x2f07, 1, 2380}, /* KANGXI RADICAL LID */
+  {0x2f08, 1, 2381}, /* KANGXI RADICAL MAN */
+  {0x2f09, 1, 2382}, /* KANGXI RADICAL LEGS */
+  {0x2f0a, 1, 2383}, /* KANGXI RADICAL ENTER */
+  {0x2f0b, 1, 2384}, /* KANGXI RADICAL EIGHT */
+  {0x2f0c, 1, 2385}, /* KANGXI RADICAL DOWN BOX */
+  {0x2f0d, 1, 2386}, /* KANGXI RADICAL COVER */
+  {0x2f0e, 1, 2387}, /* KANGXI RADICAL ICE */
+  {0x2f0f, 1, 2388}, /* KANGXI RADICAL TABLE */
+  {0x2f10, 1, 2389}, /* KANGXI RADICAL OPEN BOX */
+  {0x2f11, 1, 2390}, /* KANGXI RADICAL KNIFE */
+  {0x2f12, 1, 2391}, /* KANGXI RADICAL POWER */
+  {0x2f13, 1, 2392}, /* KANGXI RADICAL WRAP */
+  {0x2f14, 1, 2393}, /* KANGXI RADICAL SPOON */
+  {0x2f15, 1, 2394}, /* KANGXI RADICAL RIGHT OPEN BOX */
+  {0x2f16, 1, 2395}, /* KANGXI RADICAL HIDING ENCLOSURE */
+  {0x2f17, 1, 2396}, /* KANGXI RADICAL TEN */
+  {0x2f18, 1, 2397}, /* KANGXI RADICAL DIVINATION */
+  {0x2f19, 1, 2398}, /* KANGXI RADICAL SEAL */
+  {0x2f1a, 1, 2399}, /* KANGXI RADICAL CLIFF */
+  {0x2f1b, 1, 2400}, /* KANGXI RADICAL PRIVATE */
+  {0x2f1c, 1, 2401}, /* KANGXI RADICAL AGAIN */
+  {0x2f1d, 1, 2402}, /* KANGXI RADICAL MOUTH */
+  {0x2f1e, 1, 2403}, /* KANGXI RADICAL ENCLOSURE */
+  {0x2f1f, 1, 2404}, /* KANGXI RADICAL EARTH */
+  {0x2f20, 1, 2405}, /* KANGXI RADICAL SCHOLAR */
+  {0x2f21, 1, 2406}, /* KANGXI RADICAL GO */
+  {0x2f22, 1, 2407}, /* KANGXI RADICAL GO SLOWLY */
+  {0x2f23, 1, 2408}, /* KANGXI RADICAL EVENING */
+  {0x2f24, 1, 2409}, /* KANGXI RADICAL BIG */
+  {0x2f25, 1, 2410}, /* KANGXI RADICAL WOMAN */
+  {0x2f26, 1, 2411}, /* KANGXI RADICAL CHILD */
+  {0x2f27, 1, 2412}, /* KANGXI RADICAL ROOF */
+  {0x2f28, 1, 2413}, /* KANGXI RADICAL INCH */
+  {0x2f29, 1, 2414}, /* KANGXI RADICAL SMALL */
+  {0x2f2a, 1, 2415}, /* KANGXI RADICAL LAME */
+  {0x2f2b, 1, 2416}, /* KANGXI RADICAL CORPSE */
+  {0x2f2c, 1, 2417}, /* KANGXI RADICAL SPROUT */
+  {0x2f2d, 1, 2418}, /* KANGXI RADICAL MOUNTAIN */
+  {0x2f2e, 1, 2419}, /* KANGXI RADICAL RIVER */
+  {0x2f2f, 1, 2420}, /* KANGXI RADICAL WORK */
+  {0x2f30, 1, 2421}, /* KANGXI RADICAL ONESELF */
+  {0x2f31, 1, 2422}, /* KANGXI RADICAL TURBAN */
+  {0x2f32, 1, 2423}, /* KANGXI RADICAL DRY */
+  {0x2f33, 1, 2424}, /* KANGXI RADICAL SHORT THREAD */
+  {0x2f34, 1, 2425}, /* KANGXI RADICAL DOTTED CLIFF */
+  {0x2f35, 1, 2426}, /* KANGXI RADICAL LONG STRIDE */
+  {0x2f36, 1, 2427}, /* KANGXI RADICAL TWO HANDS */
+  {0x2f37, 1, 2428}, /* KANGXI RADICAL SHOOT */
+  {0x2f38, 1, 2429}, /* KANGXI RADICAL BOW */
+  {0x2f39, 1, 2430}, /* KANGXI RADICAL SNOUT */
+  {0x2f3a, 1, 2431}, /* KANGXI RADICAL BRISTLE */
+  {0x2f3b, 1, 2432}, /* KANGXI RADICAL STEP */
+  {0x2f3c, 1, 2433}, /* KANGXI RADICAL HEART */
+  {0x2f3d, 1, 2434}, /* KANGXI RADICAL HALBERD */
+  {0x2f3e, 1, 2435}, /* KANGXI RADICAL DOOR */
+  {0x2f3f, 1, 2436}, /* KANGXI RADICAL HAND */
+  {0x2f40, 1, 2437}, /* KANGXI RADICAL BRANCH */
+  {0x2f41, 1, 2438}, /* KANGXI RADICAL RAP */
+  {0x2f42, 1, 2439}, /* KANGXI RADICAL SCRIPT */
+  {0x2f43, 1, 2440}, /* KANGXI RADICAL DIPPER */
+  {0x2f44, 1, 2441}, /* KANGXI RADICAL AXE */
+  {0x2f45, 1, 2442}, /* KANGXI RADICAL SQUARE */
+  {0x2f46, 1, 2443}, /* KANGXI RADICAL NOT */
+  {0x2f47, 1, 2444}, /* KANGXI RADICAL SUN */
+  {0x2f48, 1, 2445}, /* KANGXI RADICAL SAY */
+  {0x2f49, 1, 2446}, /* KANGXI RADICAL MOON */
+  {0x2f4a, 1, 2447}, /* KANGXI RADICAL TREE */
+  {0x2f4b, 1, 2448}, /* KANGXI RADICAL LACK */
+  {0x2f4c, 1, 2449}, /* KANGXI RADICAL STOP */
+  {0x2f4d, 1, 2450}, /* KANGXI RADICAL DEATH */
+  {0x2f4e, 1, 2451}, /* KANGXI RADICAL WEAPON */
+  {0x2f4f, 1, 2452}, /* KANGXI RADICAL DO NOT */
+  {0x2f50, 1, 2453}, /* KANGXI RADICAL COMPARE */
+  {0x2f51, 1, 2454}, /* KANGXI RADICAL FUR */
+  {0x2f52, 1, 2455}, /* KANGXI RADICAL CLAN */
+  {0x2f53, 1, 2456}, /* KANGXI RADICAL STEAM */
+  {0x2f54, 1, 2457}, /* KANGXI RADICAL WATER */
+  {0x2f55, 1, 2458}, /* KANGXI RADICAL FIRE */
+  {0x2f56, 1, 2459}, /* KANGXI RADICAL CLAW */
+  {0x2f57, 1, 2460}, /* KANGXI RADICAL FATHER */
+  {0x2f58, 1, 2461}, /* KANGXI RADICAL DOUBLE X */
+  {0x2f59, 1, 2462}, /* KANGXI RADICAL HALF TREE TRUNK */
+  {0x2f5a, 1, 2463}, /* KANGXI RADICAL SLICE */
+  {0x2f5b, 1, 2464}, /* KANGXI RADICAL FANG */
+  {0x2f5c, 1, 2465}, /* KANGXI RADICAL COW */
+  {0x2f5d, 1, 2466}, /* KANGXI RADICAL DOG */
+  {0x2f5e, 1, 2467}, /* KANGXI RADICAL PROFOUND */
+  {0x2f5f, 1, 2468}, /* KANGXI RADICAL JADE */
+  {0x2f60, 1, 2469}, /* KANGXI RADICAL MELON */
+  {0x2f61, 1, 2470}, /* KANGXI RADICAL TILE */
+  {0x2f62, 1, 2471}, /* KANGXI RADICAL SWEET */
+  {0x2f63, 1, 2472}, /* KANGXI RADICAL LIFE */
+  {0x2f64, 1, 2473}, /* KANGXI RADICAL USE */
+  {0x2f65, 1, 2474}, /* KANGXI RADICAL FIELD */
+  {0x2f66, 1, 2475}, /* KANGXI RADICAL BOLT OF CLOTH */
+  {0x2f67, 1, 2476}, /* KANGXI RADICAL SICKNESS */
+  {0x2f68, 1, 2477}, /* KANGXI RADICAL DOTTED TENT */
+  {0x2f69, 1, 2478}, /* KANGXI RADICAL WHITE */
+  {0x2f6a, 1, 2479}, /* KANGXI RADICAL SKIN */
+  {0x2f6b, 1, 2480}, /* KANGXI RADICAL DISH */
+  {0x2f6c, 1, 2481}, /* KANGXI RADICAL EYE */
+  {0x2f6d, 1, 2482}, /* KANGXI RADICAL SPEAR */
+  {0x2f6e, 1, 2483}, /* KANGXI RADICAL ARROW */
+  {0x2f6f, 1, 2484}, /* KANGXI RADICAL STONE */
+  {0x2f70, 1, 2485}, /* KANGXI RADICAL SPIRIT */
+  {0x2f71, 1, 2486}, /* KANGXI RADICAL TRACK */
+  {0x2f72, 1, 2487}, /* KANGXI RADICAL GRAIN */
+  {0x2f73, 1, 2488}, /* KANGXI RADICAL CAVE */
+  {0x2f74, 1, 2489}, /* KANGXI RADICAL STAND */
+  {0x2f75, 1, 2490}, /* KANGXI RADICAL BAMBOO */
+  {0x2f76, 1, 2491}, /* KANGXI RADICAL RICE */
+  {0x2f77, 1, 2492}, /* KANGXI RADICAL SILK */
+  {0x2f78, 1, 2493}, /* KANGXI RADICAL JAR */
+  {0x2f79, 1, 2494}, /* KANGXI RADICAL NET */
+  {0x2f7a, 1, 2495}, /* KANGXI RADICAL SHEEP */
+  {0x2f7b, 1, 2496}, /* KANGXI RADICAL FEATHER */
+  {0x2f7c, 1, 2497}, /* KANGXI RADICAL OLD */
+  {0x2f7d, 1, 2498}, /* KANGXI RADICAL AND */
+  {0x2f7e, 1, 2499}, /* KANGXI RADICAL PLOW */
+  {0x2f7f, 1, 2500}, /* KANGXI RADICAL EAR */
+  {0x2f80, 1, 2501}, /* KANGXI RADICAL BRUSH */
+  {0x2f81, 1, 2502}, /* KANGXI RADICAL MEAT */
+  {0x2f82, 1, 2503}, /* KANGXI RADICAL MINISTER */
+  {0x2f83, 1, 2504}, /* KANGXI RADICAL SELF */
+  {0x2f84, 1, 2505}, /* KANGXI RADICAL ARRIVE */
+  {0x2f85, 1, 2506}, /* KANGXI RADICAL MORTAR */
+  {0x2f86, 1, 2507}, /* KANGXI RADICAL TONGUE */
+  {0x2f87, 1, 2508}, /* KANGXI RADICAL OPPOSE */
+  {0x2f88, 1, 2509}, /* KANGXI RADICAL BOAT */
+  {0x2f89, 1, 2510}, /* KANGXI RADICAL STOPPING */
+  {0x2f8a, 1, 2511}, /* KANGXI RADICAL COLOR */
+  {0x2f8b, 1, 2512}, /* KANGXI RADICAL GRASS */
+  {0x2f8c, 1, 2513}, /* KANGXI RADICAL TIGER */
+  {0x2f8d, 1, 2514}, /* KANGXI RADICAL INSECT */
+  {0x2f8e, 1, 2515}, /* KANGXI RADICAL BLOOD */
+  {0x2f8f, 1, 2516}, /* KANGXI RADICAL WALK ENCLOSURE */
+  {0x2f90, 1, 2517}, /* KANGXI RADICAL CLOTHES */
+  {0x2f91, 1, 2518}, /* KANGXI RADICAL WEST */
+  {0x2f92, 1, 2519}, /* KANGXI RADICAL SEE */
+  {0x2f93, 1, 2520}, /* KANGXI RADICAL HORN */
+  {0x2f94, 1, 2521}, /* KANGXI RADICAL SPEECH */
+  {0x2f95, 1, 2522}, /* KANGXI RADICAL VALLEY */
+  {0x2f96, 1, 2523}, /* KANGXI RADICAL BEAN */
+  {0x2f97, 1, 2524}, /* KANGXI RADICAL PIG */
+  {0x2f98, 1, 2525}, /* KANGXI RADICAL BADGER */
+  {0x2f99, 1, 2526}, /* KANGXI RADICAL SHELL */
+  {0x2f9a, 1, 2527}, /* KANGXI RADICAL RED */
+  {0x2f9b, 1, 2528}, /* KANGXI RADICAL RUN */
+  {0x2f9c, 1, 2529}, /* KANGXI RADICAL FOOT */
+  {0x2f9d, 1, 2530}, /* KANGXI RADICAL BODY */
+  {0x2f9e, 1, 2531}, /* KANGXI RADICAL CART */
+  {0x2f9f, 1, 2532}, /* KANGXI RADICAL BITTER */
+  {0x2fa0, 1, 2533}, /* KANGXI RADICAL MORNING */
+  {0x2fa1, 1, 2534}, /* KANGXI RADICAL WALK */
+  {0x2fa2, 1, 2535}, /* KANGXI RADICAL CITY */
+  {0x2fa3, 1, 2536}, /* KANGXI RADICAL WINE */
+  {0x2fa4, 1, 2537}, /* KANGXI RADICAL DISTINGUISH */
+  {0x2fa5, 1, 2538}, /* KANGXI RADICAL VILLAGE */
+  {0x2fa6, 1, 2539}, /* KANGXI RADICAL GOLD */
+  {0x2fa7, 1, 2540}, /* KANGXI RADICAL LONG */
+  {0x2fa8, 1, 2541}, /* KANGXI RADICAL GATE */
+  {0x2fa9, 1, 2542}, /* KANGXI RADICAL MOUND */
+  {0x2faa, 1, 2543}, /* KANGXI RADICAL SLAVE */
+  {0x2fab, 1, 2544}, /* KANGXI RADICAL SHORT TAILED BIRD */
+  {0x2fac, 1, 2545}, /* KANGXI RADICAL RAIN */
+  {0x2fad, 1, 2546}, /* KANGXI RADICAL BLUE */
+  {0x2fae, 1, 2547}, /* KANGXI RADICAL WRONG */
+  {0x2faf, 1, 2548}, /* KANGXI RADICAL FACE */
+  {0x2fb0, 1, 2549}, /* KANGXI RADICAL LEATHER */
+  {0x2fb1, 1, 2550}, /* KANGXI RADICAL TANNED LEATHER */
+  {0x2fb2, 1, 2551}, /* KANGXI RADICAL LEEK */
+  {0x2fb3, 1, 2552}, /* KANGXI RADICAL SOUND */
+  {0x2fb4, 1, 2553}, /* KANGXI RADICAL LEAF */
+  {0x2fb5, 1, 2554}, /* KANGXI RADICAL WIND */
+  {0x2fb6, 1, 2555}, /* KANGXI RADICAL FLY */
+  {0x2fb7, 1, 2556}, /* KANGXI RADICAL EAT */
+  {0x2fb8, 1, 2557}, /* KANGXI RADICAL HEAD */
+  {0x2fb9, 1, 2558}, /* KANGXI RADICAL FRAGRANT */
+  {0x2fba, 1, 2559}, /* KANGXI RADICAL HORSE */
+  {0x2fbb, 1, 2560}, /* KANGXI RADICAL BONE */
+  {0x2fbc, 1, 2561}, /* KANGXI RADICAL TALL */
+  {0x2fbd, 1, 2562}, /* KANGXI RADICAL HAIR */
+  {0x2fbe, 1, 2563}, /* KANGXI RADICAL FIGHT */
+  {0x2fbf, 1, 2564}, /* KANGXI RADICAL SACRIFICIAL WINE */
+  {0x2fc0, 1, 2565}, /* KANGXI RADICAL CAULDRON */
+  {0x2fc1, 1, 2566}, /* KANGXI RADICAL GHOST */
+  {0x2fc2, 1, 2567}, /* KANGXI RADICAL FISH */
+  {0x2fc3, 1, 2568}, /* KANGXI RADICAL BIRD */
+  {0x2fc4, 1, 2569}, /* KANGXI RADICAL SALT */
+  {0x2fc5, 1, 2570}, /* KANGXI RADICAL DEER */
+  {0x2fc6, 1, 2571}, /* KANGXI RADICAL WHEAT */
+  {0x2fc7, 1, 2572}, /* KANGXI RADICAL HEMP */
+  {0x2fc8, 1, 2573}, /* KANGXI RADICAL YELLOW */
+  {0x2fc9, 1, 2574}, /* KANGXI RADICAL MILLET */
+  {0x2fca, 1, 2575}, /* KANGXI RADICAL BLACK */
+  {0x2fcb, 1, 2576}, /* KANGXI RADICAL EMBROIDERY */
+  {0x2fcc, 1, 2577}, /* KANGXI RADICAL FROG */
+  {0x2fcd, 1, 2578}, /* KANGXI RADICAL TRIPOD */
+  {0x2fce, 1, 2579}, /* KANGXI RADICAL DRUM */
+  {0x2fcf, 1, 2580}, /* KANGXI RADICAL RAT */
+  {0x2fd0, 1, 2581}, /* KANGXI RADICAL NOSE */
+  {0x2fd1, 1, 2582}, /* KANGXI RADICAL EVEN */
+  {0x2fd2, 1, 2583}, /* KANGXI RADICAL TOOTH */
+  {0x2fd3, 1, 2584}, /* KANGXI RADICAL DRAGON */
+  {0x2fd4, 1, 2585}, /* KANGXI RADICAL TURTLE */
+  {0x2fd5, 1, 2586}, /* KANGXI RADICAL FLUTE */
+  {0x3000, 1, 2587}, /* IDEOGRAPHIC SPACE */
+  {0x3036, 1, 2588}, /* CIRCLED POSTAL MARK */
+  {0x3038, 1, 2396}, /* HANGZHOU NUMERAL TEN */
+  {0x3039, 1, 2589}, /* HANGZHOU NUMERAL TWENTY */
+  {0x303a, 1, 2590}, /* HANGZHOU NUMERAL THIRTY */
+  {0x304c, 2, 2591}, /* HIRAGANA LETTER GA */
+  {0x304e, 2, 2593}, /* HIRAGANA LETTER GI */
+  {0x3050, 2, 2595}, /* HIRAGANA LETTER GU */
+  {0x3052, 2, 2597}, /* HIRAGANA LETTER GE */
+  {0x3054, 2, 2599}, /* HIRAGANA LETTER GO */
+  {0x3056, 2, 2601}, /* HIRAGANA LETTER ZA */
+  {0x3058, 2, 2603}, /* HIRAGANA LETTER ZI */
+  {0x305a, 2, 2605}, /* HIRAGANA LETTER ZU */
+  {0x305c, 2, 2607}, /* HIRAGANA LETTER ZE */
+  {0x305e, 2, 2609}, /* HIRAGANA LETTER ZO */
+  {0x3060, 2, 2611}, /* HIRAGANA LETTER DA */
+  {0x3062, 2, 2613}, /* HIRAGANA LETTER DI */
+  {0x3065, 2, 2615}, /* HIRAGANA LETTER DU */
+  {0x3067, 2, 2617}, /* HIRAGANA LETTER DE */
+  {0x3069, 2, 2619}, /* HIRAGANA LETTER DO */
+  {0x3070, 2, 2621}, /* HIRAGANA LETTER BA */
+  {0x3071, 2, 2623}, /* HIRAGANA LETTER PA */
+  {0x3073, 2, 2625}, /* HIRAGANA LETTER BI */
+  {0x3074, 2, 2627}, /* HIRAGANA LETTER PI */
+  {0x3076, 2, 2629}, /* HIRAGANA LETTER BU */
+  {0x3077, 2, 2631}, /* HIRAGANA LETTER PU */
+  {0x3079, 2, 2633}, /* HIRAGANA LETTER BE */
+  {0x307a, 2, 2635}, /* HIRAGANA LETTER PE */
+  {0x307c, 2, 2637}, /* HIRAGANA LETTER BO */
+  {0x307d, 2, 2639}, /* HIRAGANA LETTER PO */
+  {0x3094, 2, 2641}, /* HIRAGANA LETTER VU */
+  {0x309b, 2, 2643}, /* KATAKANA-HIRAGANA VOICED SOUND MARK */
+  {0x309c, 2, 2645}, /* KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+  {0x309e, 2, 2647}, /* HIRAGANA VOICED ITERATION MARK */
+  {0x309f, 2, 2649}, /* HIRAGANA DIGRAPH YORI */
+  {0x30ac, 2, 2651}, /* KATAKANA LETTER GA */
+  {0x30ae, 2, 2653}, /* KATAKANA LETTER GI */
+  {0x30b0, 2, 2655}, /* KATAKANA LETTER GU */
+  {0x30b2, 2, 2657}, /* KATAKANA LETTER GE */
+  {0x30b4, 2, 2659}, /* KATAKANA LETTER GO */
+  {0x30b6, 2, 2661}, /* KATAKANA LETTER ZA */
+  {0x30b8, 2, 2663}, /* KATAKANA LETTER ZI */
+  {0x30ba, 2, 2665}, /* KATAKANA LETTER ZU */
+  {0x30bc, 2, 2667}, /* KATAKANA LETTER ZE */
+  {0x30be, 2, 2669}, /* KATAKANA LETTER ZO */
+  {0x30c0, 2, 2671}, /* KATAKANA LETTER DA */
+  {0x30c2, 2, 2673}, /* KATAKANA LETTER DI */
+  {0x30c5, 2, 2675}, /* KATAKANA LETTER DU */
+  {0x30c7, 2, 2677}, /* KATAKANA LETTER DE */
+  {0x30c9, 2, 2679}, /* KATAKANA LETTER DO */
+  {0x30d0, 2, 2681}, /* KATAKANA LETTER BA */
+  {0x30d1, 2, 2683}, /* KATAKANA LETTER PA */
+  {0x30d3, 2, 2685}, /* KATAKANA LETTER BI */
+  {0x30d4, 2, 2687}, /* KATAKANA LETTER PI */
+  {0x30d6, 2, 2689}, /* KATAKANA LETTER BU */
+  {0x30d7, 2, 2691}, /* KATAKANA LETTER PU */
+  {0x30d9, 2, 2693}, /* KATAKANA LETTER BE */
+  {0x30da, 2, 2695}, /* KATAKANA LETTER PE */
+  {0x30dc, 2, 2697}, /* KATAKANA LETTER BO */
+  {0x30dd, 2, 2699}, /* KATAKANA LETTER PO */
+  {0x30f4, 2, 2701}, /* KATAKANA LETTER VU */
+  {0x30f7, 2, 2703}, /* KATAKANA LETTER VA */
+  {0x30f8, 2, 2705}, /* KATAKANA LETTER VI */
+  {0x30f9, 2, 2707}, /* KATAKANA LETTER VE */
+  {0x30fa, 2, 2709}, /* KATAKANA LETTER VO */
+  {0x30fe, 2, 2711}, /* KATAKANA VOICED ITERATION MARK */
+  {0x30ff, 2, 2713}, /* KATAKANA DIGRAPH KOTO */
+  {0x3131, 1, 2715}, /* HANGUL LETTER KIYEOK */
+  {0x3132, 1, 2716}, /* HANGUL LETTER SSANGKIYEOK */
+  {0x3133, 1, 2717}, /* HANGUL LETTER KIYEOK-SIOS */
+  {0x3134, 1, 2718}, /* HANGUL LETTER NIEUN */
+  {0x3135, 1, 2719}, /* HANGUL LETTER NIEUN-CIEUC */
+  {0x3136, 1, 2720}, /* HANGUL LETTER NIEUN-HIEUH */
+  {0x3137, 1, 2721}, /* HANGUL LETTER TIKEUT */
+  {0x3138, 1, 2722}, /* HANGUL LETTER SSANGTIKEUT */
+  {0x3139, 1, 2723}, /* HANGUL LETTER RIEUL */
+  {0x313a, 1, 2724}, /* HANGUL LETTER RIEUL-KIYEOK */
+  {0x313b, 1, 2725}, /* HANGUL LETTER RIEUL-MIEUM */
+  {0x313c, 1, 2726}, /* HANGUL LETTER RIEUL-PIEUP */
+  {0x313d, 1, 2727}, /* HANGUL LETTER RIEUL-SIOS */
+  {0x313e, 1, 2728}, /* HANGUL LETTER RIEUL-THIEUTH */
+  {0x313f, 1, 2729}, /* HANGUL LETTER RIEUL-PHIEUPH */
+  {0x3140, 1, 2730}, /* HANGUL LETTER RIEUL-HIEUH */
+  {0x3141, 1, 2731}, /* HANGUL LETTER MIEUM */
+  {0x3142, 1, 2732}, /* HANGUL LETTER PIEUP */
+  {0x3143, 1, 2733}, /* HANGUL LETTER SSANGPIEUP */
+  {0x3144, 1, 2734}, /* HANGUL LETTER PIEUP-SIOS */
+  {0x3145, 1, 2735}, /* HANGUL LETTER SIOS */
+  {0x3146, 1, 2736}, /* HANGUL LETTER SSANGSIOS */
+  {0x3147, 1, 2737}, /* HANGUL LETTER IEUNG */
+  {0x3148, 1, 2738}, /* HANGUL LETTER CIEUC */
+  {0x3149, 1, 2739}, /* HANGUL LETTER SSANGCIEUC */
+  {0x314a, 1, 2740}, /* HANGUL LETTER CHIEUCH */
+  {0x314b, 1, 2741}, /* HANGUL LETTER KHIEUKH */
+  {0x314c, 1, 2742}, /* HANGUL LETTER THIEUTH */
+  {0x314d, 1, 2743}, /* HANGUL LETTER PHIEUPH */
+  {0x314e, 1, 2744}, /* HANGUL LETTER HIEUH */
+  {0x314f, 1, 2745}, /* HANGUL LETTER A */
+  {0x3150, 1, 2746}, /* HANGUL LETTER AE */
+  {0x3151, 1, 2747}, /* HANGUL LETTER YA */
+  {0x3152, 1, 2748}, /* HANGUL LETTER YAE */
+  {0x3153, 1, 2749}, /* HANGUL LETTER EO */
+  {0x3154, 1, 2750}, /* HANGUL LETTER E */
+  {0x3155, 1, 2751}, /* HANGUL LETTER YEO */
+  {0x3156, 1, 2752}, /* HANGUL LETTER YE */
+  {0x3157, 1, 2753}, /* HANGUL LETTER O */
+  {0x3158, 1, 2754}, /* HANGUL LETTER WA */
+  {0x3159, 1, 2755}, /* HANGUL LETTER WAE */
+  {0x315a, 1, 2756}, /* HANGUL LETTER OE */
+  {0x315b, 1, 2757}, /* HANGUL LETTER YO */
+  {0x315c, 1, 2758}, /* HANGUL LETTER U */
+  {0x315d, 1, 2759}, /* HANGUL LETTER WEO */
+  {0x315e, 1, 2760}, /* HANGUL LETTER WE */
+  {0x315f, 1, 2761}, /* HANGUL LETTER WI */
+  {0x3160, 1, 2762}, /* HANGUL LETTER YU */
+  {0x3161, 1, 2763}, /* HANGUL LETTER EU */
+  {0x3162, 1, 2764}, /* HANGUL LETTER YI */
+  {0x3163, 1, 2765}, /* HANGUL LETTER I */
+  {0x3164, 1, 2766}, /* HANGUL FILLER */
+  {0x3165, 1, 2767}, /* HANGUL LETTER SSANGNIEUN */
+  {0x3166, 1, 2768}, /* HANGUL LETTER NIEUN-TIKEUT */
+  {0x3167, 1, 2769}, /* HANGUL LETTER NIEUN-SIOS */
+  {0x3168, 1, 2770}, /* HANGUL LETTER NIEUN-PANSIOS */
+  {0x3169, 1, 2771}, /* HANGUL LETTER RIEUL-KIYEOK-SIOS */
+  {0x316a, 1, 2772}, /* HANGUL LETTER RIEUL-TIKEUT */
+  {0x316b, 1, 2773}, /* HANGUL LETTER RIEUL-PIEUP-SIOS */
+  {0x316c, 1, 2774}, /* HANGUL LETTER RIEUL-PANSIOS */
+  {0x316d, 1, 2775}, /* HANGUL LETTER RIEUL-YEORINHIEUH */
+  {0x316e, 1, 2776}, /* HANGUL LETTER MIEUM-PIEUP */
+  {0x316f, 1, 2777}, /* HANGUL LETTER MIEUM-SIOS */
+  {0x3170, 1, 2778}, /* HANGUL LETTER MIEUM-PANSIOS */
+  {0x3171, 1, 2779}, /* HANGUL LETTER KAPYEOUNMIEUM */
+  {0x3172, 1, 2780}, /* HANGUL LETTER PIEUP-KIYEOK */
+  {0x3173, 1, 2781}, /* HANGUL LETTER PIEUP-TIKEUT */
+  {0x3174, 1, 2782}, /* HANGUL LETTER PIEUP-SIOS-KIYEOK */
+  {0x3175, 1, 2783}, /* HANGUL LETTER PIEUP-SIOS-TIKEUT */
+  {0x3176, 1, 2784}, /* HANGUL LETTER PIEUP-CIEUC */
+  {0x3177, 1, 2785}, /* HANGUL LETTER PIEUP-THIEUTH */
+  {0x3178, 1, 2786}, /* HANGUL LETTER KAPYEOUNPIEUP */
+  {0x3179, 1, 2787}, /* HANGUL LETTER KAPYEOUNSSANGPIEUP */
+  {0x317a, 1, 2788}, /* HANGUL LETTER SIOS-KIYEOK */
+  {0x317b, 1, 2789}, /* HANGUL LETTER SIOS-NIEUN */
+  {0x317c, 1, 2790}, /* HANGUL LETTER SIOS-TIKEUT */
+  {0x317d, 1, 2791}, /* HANGUL LETTER SIOS-PIEUP */
+  {0x317e, 1, 2792}, /* HANGUL LETTER SIOS-CIEUC */
+  {0x317f, 1, 2793}, /* HANGUL LETTER PANSIOS */
+  {0x3180, 1, 2794}, /* HANGUL LETTER SSANGIEUNG */
+  {0x3181, 1, 2795}, /* HANGUL LETTER YESIEUNG */
+  {0x3182, 1, 2796}, /* HANGUL LETTER YESIEUNG-SIOS */
+  {0x3183, 1, 2797}, /* HANGUL LETTER YESIEUNG-PANSIOS */
+  {0x3184, 1, 2798}, /* HANGUL LETTER KAPYEOUNPHIEUPH */
+  {0x3185, 1, 2799}, /* HANGUL LETTER SSANGHIEUH */
+  {0x3186, 1, 2800}, /* HANGUL LETTER YEORINHIEUH */
+  {0x3187, 1, 2801}, /* HANGUL LETTER YO-YA */
+  {0x3188, 1, 2802}, /* HANGUL LETTER YO-YAE */
+  {0x3189, 1, 2803}, /* HANGUL LETTER YO-I */
+  {0x318a, 1, 2804}, /* HANGUL LETTER YU-YEO */
+  {0x318b, 1, 2805}, /* HANGUL LETTER YU-YE */
+  {0x318c, 1, 2806}, /* HANGUL LETTER YU-I */
+  {0x318d, 1, 2807}, /* HANGUL LETTER ARAEA */
+  {0x318e, 1, 2808}, /* HANGUL LETTER ARAEAE */
+  {0x3192, 1, 2373}, /* IDEOGRAPHIC ANNOTATION ONE MARK */
+  {0x3193, 1, 2379}, /* IDEOGRAPHIC ANNOTATION TWO MARK */
+  {0x3194, 1, 2809}, /* IDEOGRAPHIC ANNOTATION THREE MARK */
+  {0x3195, 1, 2810}, /* IDEOGRAPHIC ANNOTATION FOUR MARK */
+  {0x3196, 1, 2811}, /* IDEOGRAPHIC ANNOTATION TOP MARK */
+  {0x3197, 1, 2812}, /* IDEOGRAPHIC ANNOTATION MIDDLE MARK */
+  {0x3198, 1, 2813}, /* IDEOGRAPHIC ANNOTATION BOTTOM MARK */
+  {0x3199, 1, 2814}, /* IDEOGRAPHIC ANNOTATION FIRST MARK */
+  {0x319a, 1, 2377}, /* IDEOGRAPHIC ANNOTATION SECOND MARK */
+  {0x319b, 1, 2815}, /* IDEOGRAPHIC ANNOTATION THIRD MARK */
+  {0x319c, 1, 2816}, /* IDEOGRAPHIC ANNOTATION FOURTH MARK */
+  {0x319d, 1, 2817}, /* IDEOGRAPHIC ANNOTATION HEAVEN MARK */
+  {0x319e, 1, 2818}, /* IDEOGRAPHIC ANNOTATION EARTH MARK */
+  {0x319f, 1, 2381}, /* IDEOGRAPHIC ANNOTATION MAN MARK */
+  {0x3200, 3, 2819}, /* PARENTHESIZED HANGUL KIYEOK */
+  {0x3201, 3, 2822}, /* PARENTHESIZED HANGUL NIEUN */
+  {0x3202, 3, 2825}, /* PARENTHESIZED HANGUL TIKEUT */
+  {0x3203, 3, 2828}, /* PARENTHESIZED HANGUL RIEUL */
+  {0x3204, 3, 2831}, /* PARENTHESIZED HANGUL MIEUM */
+  {0x3205, 3, 2834}, /* PARENTHESIZED HANGUL PIEUP */
+  {0x3206, 3, 2837}, /* PARENTHESIZED HANGUL SIOS */
+  {0x3207, 3, 2840}, /* PARENTHESIZED HANGUL IEUNG */
+  {0x3208, 3, 2843}, /* PARENTHESIZED HANGUL CIEUC */
+  {0x3209, 3, 2846}, /* PARENTHESIZED HANGUL CHIEUCH */
+  {0x320a, 3, 2849}, /* PARENTHESIZED HANGUL KHIEUKH */
+  {0x320b, 3, 2852}, /* PARENTHESIZED HANGUL THIEUTH */
+  {0x320c, 3, 2855}, /* PARENTHESIZED HANGUL PHIEUPH */
+  {0x320d, 3, 2858}, /* PARENTHESIZED HANGUL HIEUH */
+  {0x320e, 4, 2861}, /* PARENTHESIZED HANGUL KIYEOK A */
+  {0x320f, 4, 2865}, /* PARENTHESIZED HANGUL NIEUN A */
+  {0x3210, 4, 2869}, /* PARENTHESIZED HANGUL TIKEUT A */
+  {0x3211, 4, 2873}, /* PARENTHESIZED HANGUL RIEUL A */
+  {0x3212, 4, 2877}, /* PARENTHESIZED HANGUL MIEUM A */
+  {0x3213, 4, 2881}, /* PARENTHESIZED HANGUL PIEUP A */
+  {0x3214, 4, 2885}, /* PARENTHESIZED HANGUL SIOS A */
+  {0x3215, 4, 2889}, /* PARENTHESIZED HANGUL IEUNG A */
+  {0x3216, 4, 2893}, /* PARENTHESIZED HANGUL CIEUC A */
+  {0x3217, 4, 2897}, /* PARENTHESIZED HANGUL CHIEUCH A */
+  {0x3218, 4, 2901}, /* PARENTHESIZED HANGUL KHIEUKH A */
+  {0x3219, 4, 2905}, /* PARENTHESIZED HANGUL THIEUTH A */
+  {0x321a, 4, 2909}, /* PARENTHESIZED HANGUL PHIEUPH A */
+  {0x321b, 4, 2913}, /* PARENTHESIZED HANGUL HIEUH A */
+  {0x321c, 4, 2917}, /* PARENTHESIZED HANGUL CIEUC U */
+  {0x321d, 7, 2921}, /* PARENTHESIZED KOREAN CHARACTER OJEON */
+  {0x321e, 6, 2928}, /* PARENTHESIZED KOREAN CHARACTER O HU */
+  {0x3220, 3, 2934}, /* PARENTHESIZED IDEOGRAPH ONE */
+  {0x3221, 3, 2937}, /* PARENTHESIZED IDEOGRAPH TWO */
+  {0x3222, 3, 2940}, /* PARENTHESIZED IDEOGRAPH THREE */
+  {0x3223, 3, 2943}, /* PARENTHESIZED IDEOGRAPH FOUR */
+  {0x3224, 3, 2946}, /* PARENTHESIZED IDEOGRAPH FIVE */
+  {0x3225, 3, 2949}, /* PARENTHESIZED IDEOGRAPH SIX */
+  {0x3226, 3, 2952}, /* PARENTHESIZED IDEOGRAPH SEVEN */
+  {0x3227, 3, 2955}, /* PARENTHESIZED IDEOGRAPH EIGHT */
+  {0x3228, 3, 2958}, /* PARENTHESIZED IDEOGRAPH NINE */
+  {0x3229, 3, 2961}, /* PARENTHESIZED IDEOGRAPH TEN */
+  {0x322a, 3, 2964}, /* PARENTHESIZED IDEOGRAPH MOON */
+  {0x322b, 3, 2967}, /* PARENTHESIZED IDEOGRAPH FIRE */
+  {0x322c, 3, 2970}, /* PARENTHESIZED IDEOGRAPH WATER */
+  {0x322d, 3, 2973}, /* PARENTHESIZED IDEOGRAPH WOOD */
+  {0x322e, 3, 2976}, /* PARENTHESIZED IDEOGRAPH METAL */
+  {0x322f, 3, 2979}, /* PARENTHESIZED IDEOGRAPH EARTH */
+  {0x3230, 3, 2982}, /* PARENTHESIZED IDEOGRAPH SUN */
+  {0x3231, 3, 2985}, /* PARENTHESIZED IDEOGRAPH STOCK */
+  {0x3232, 3, 2988}, /* PARENTHESIZED IDEOGRAPH HAVE */
+  {0x3233, 3, 2991}, /* PARENTHESIZED IDEOGRAPH SOCIETY */
+  {0x3234, 3, 2994}, /* PARENTHESIZED IDEOGRAPH NAME */
+  {0x3235, 3, 2997}, /* PARENTHESIZED IDEOGRAPH SPECIAL */
+  {0x3236, 3, 3000}, /* PARENTHESIZED IDEOGRAPH FINANCIAL */
+  {0x3237, 3, 3003}, /* PARENTHESIZED IDEOGRAPH CONGRATULATION */
+  {0x3238, 3, 3006}, /* PARENTHESIZED IDEOGRAPH LABOR */
+  {0x3239, 3, 3009}, /* PARENTHESIZED IDEOGRAPH REPRESENT */
+  {0x323a, 3, 3012}, /* PARENTHESIZED IDEOGRAPH CALL */
+  {0x323b, 3, 3015}, /* PARENTHESIZED IDEOGRAPH STUDY */
+  {0x323c, 3, 3018}, /* PARENTHESIZED IDEOGRAPH SUPERVISE */
+  {0x323d, 3, 3021}, /* PARENTHESIZED IDEOGRAPH ENTERPRISE */
+  {0x323e, 3, 3024}, /* PARENTHESIZED IDEOGRAPH RESOURCE */
+  {0x323f, 3, 3027}, /* PARENTHESIZED IDEOGRAPH ALLIANCE */
+  {0x3240, 3, 3030}, /* PARENTHESIZED IDEOGRAPH FESTIVAL */
+  {0x3241, 3, 3033}, /* PARENTHESIZED IDEOGRAPH REST */
+  {0x3242, 3, 3036}, /* PARENTHESIZED IDEOGRAPH SELF */
+  {0x3243, 3, 3039}, /* PARENTHESIZED IDEOGRAPH REACH */
+  {0x3250, 3, 3042}, /* PARTNERSHIP SIGN */
+  {0x3251, 2, 2147}, /* CIRCLED NUMBER TWENTY ONE */
+  {0x3252, 2, 3045}, /* CIRCLED NUMBER TWENTY TWO */
+  {0x3253, 2, 6}, /* CIRCLED NUMBER TWENTY THREE */
+  {0x3254, 2, 3047}, /* CIRCLED NUMBER TWENTY FOUR */
+  {0x3255, 2, 3049}, /* CIRCLED NUMBER TWENTY FIVE */
+  {0x3256, 2, 3051}, /* CIRCLED NUMBER TWENTY SIX */
+  {0x3257, 2, 3053}, /* CIRCLED NUMBER TWENTY SEVEN */
+  {0x3258, 2, 3055}, /* CIRCLED NUMBER TWENTY EIGHT */
+  {0x3259, 2, 3057}, /* CIRCLED NUMBER TWENTY NINE */
+  {0x325a, 2, 3059}, /* CIRCLED NUMBER THIRTY */
+  {0x325b, 2, 1965}, /* CIRCLED NUMBER THIRTY ONE */
+  {0x325c, 2, 1962}, /* CIRCLED NUMBER THIRTY TWO */
+  {0x325d, 2, 3061}, /* CIRCLED NUMBER THIRTY THREE */
+  {0x325e, 2, 3063}, /* CIRCLED NUMBER THIRTY FOUR */
+  {0x325f, 2, 3065}, /* CIRCLED NUMBER THIRTY FIVE */
+  {0x3260, 1, 2715}, /* CIRCLED HANGUL KIYEOK */
+  {0x3261, 1, 2718}, /* CIRCLED HANGUL NIEUN */
+  {0x3262, 1, 2721}, /* CIRCLED HANGUL TIKEUT */
+  {0x3263, 1, 2723}, /* CIRCLED HANGUL RIEUL */
+  {0x3264, 1, 2731}, /* CIRCLED HANGUL MIEUM */
+  {0x3265, 1, 2732}, /* CIRCLED HANGUL PIEUP */
+  {0x3266, 1, 2735}, /* CIRCLED HANGUL SIOS */
+  {0x3267, 1, 2737}, /* CIRCLED HANGUL IEUNG */
+  {0x3268, 1, 2738}, /* CIRCLED HANGUL CIEUC */
+  {0x3269, 1, 2740}, /* CIRCLED HANGUL CHIEUCH */
+  {0x326a, 1, 2741}, /* CIRCLED HANGUL KHIEUKH */
+  {0x326b, 1, 2742}, /* CIRCLED HANGUL THIEUTH */
+  {0x326c, 1, 2743}, /* CIRCLED HANGUL PHIEUPH */
+  {0x326d, 1, 2744}, /* CIRCLED HANGUL HIEUH */
+  {0x326e, 2, 2862}, /* CIRCLED HANGUL KIYEOK A */
+  {0x326f, 2, 2866}, /* CIRCLED HANGUL NIEUN A */
+  {0x3270, 2, 2870}, /* CIRCLED HANGUL TIKEUT A */
+  {0x3271, 2, 2874}, /* CIRCLED HANGUL RIEUL A */
+  {0x3272, 2, 2878}, /* CIRCLED HANGUL MIEUM A */
+  {0x3273, 2, 2882}, /* CIRCLED HANGUL PIEUP A */
+  {0x3274, 2, 2886}, /* CIRCLED HANGUL SIOS A */
+  {0x3275, 2, 2890}, /* CIRCLED HANGUL IEUNG A */
+  {0x3276, 2, 2894}, /* CIRCLED HANGUL CIEUC A */
+  {0x3277, 2, 2898}, /* CIRCLED HANGUL CHIEUCH A */
+  {0x3278, 2, 2902}, /* CIRCLED HANGUL KHIEUKH A */
+  {0x3279, 2, 2906}, /* CIRCLED HANGUL THIEUTH A */
+  {0x327a, 2, 2910}, /* CIRCLED HANGUL PHIEUPH A */
+  {0x327b, 2, 2744}, /* CIRCLED HANGUL HIEUH A */
+  {0x327c, 5, 3067}, /* CIRCLED KOREAN CHARACTER CHAMKO */
+  {0x327d, 4, 3072}, /* CIRCLED KOREAN CHARACTER JUEUI */
+  {0x3280, 1, 2373}, /* CIRCLED IDEOGRAPH ONE */
+  {0x3281, 1, 2379}, /* CIRCLED IDEOGRAPH TWO */
+  {0x3282, 1, 2809}, /* CIRCLED IDEOGRAPH THREE */
+  {0x3283, 1, 2810}, /* CIRCLED IDEOGRAPH FOUR */
+  {0x3284, 1, 2947}, /* CIRCLED IDEOGRAPH FIVE */
+  {0x3285, 1, 2950}, /* CIRCLED IDEOGRAPH SIX */
+  {0x3286, 1, 2953}, /* CIRCLED IDEOGRAPH SEVEN */
+  {0x3287, 1, 2384}, /* CIRCLED IDEOGRAPH EIGHT */
+  {0x3288, 1, 2959}, /* CIRCLED IDEOGRAPH NINE */
+  {0x3289, 1, 2396}, /* CIRCLED IDEOGRAPH TEN */
+  {0x328a, 1, 2446}, /* CIRCLED IDEOGRAPH MOON */
+  {0x328b, 1, 2458}, /* CIRCLED IDEOGRAPH FIRE */
+  {0x328c, 1, 2457}, /* CIRCLED IDEOGRAPH WATER */
+  {0x328d, 1, 2447}, /* CIRCLED IDEOGRAPH WOOD */
+  {0x328e, 1, 2539}, /* CIRCLED IDEOGRAPH METAL */
+  {0x328f, 1, 2404}, /* CIRCLED IDEOGRAPH EARTH */
+  {0x3290, 1, 2444}, /* CIRCLED IDEOGRAPH SUN */
+  {0x3291, 1, 2986}, /* CIRCLED IDEOGRAPH STOCK */
+  {0x3292, 1, 2989}, /* CIRCLED IDEOGRAPH HAVE */
+  {0x3293, 1, 2992}, /* CIRCLED IDEOGRAPH SOCIETY */
+  {0x3294, 1, 2995}, /* CIRCLED IDEOGRAPH NAME */
+  {0x3295, 1, 2998}, /* CIRCLED IDEOGRAPH SPECIAL */
+  {0x3296, 1, 3001}, /* CIRCLED IDEOGRAPH FINANCIAL */
+  {0x3297, 1, 3004}, /* CIRCLED IDEOGRAPH CONGRATULATION */
+  {0x3298, 1, 3007}, /* CIRCLED IDEOGRAPH LABOR */
+  {0x3299, 1, 3076}, /* CIRCLED IDEOGRAPH SECRET */
+  {0x329a, 1, 3077}, /* CIRCLED IDEOGRAPH MALE */
+  {0x329b, 1, 2410}, /* CIRCLED IDEOGRAPH FEMALE */
+  {0x329c, 1, 3078}, /* CIRCLED IDEOGRAPH SUITABLE */
+  {0x329d, 1, 3079}, /* CIRCLED IDEOGRAPH EXCELLENT */
+  {0x329e, 1, 3080}, /* CIRCLED IDEOGRAPH PRINT */
+  {0x329f, 1, 3081}, /* CIRCLED IDEOGRAPH ATTENTION */
+  {0x32a0, 1, 3082}, /* CIRCLED IDEOGRAPH ITEM */
+  {0x32a1, 1, 3034}, /* CIRCLED IDEOGRAPH REST */
+  {0x32a2, 1, 3083}, /* CIRCLED IDEOGRAPH COPY */
+  {0x32a3, 1, 3084}, /* CIRCLED IDEOGRAPH CORRECT */
+  {0x32a4, 1, 2811}, /* CIRCLED IDEOGRAPH HIGH */
+  {0x32a5, 1, 2812}, /* CIRCLED IDEOGRAPH CENTRE */
+  {0x32a6, 1, 2813}, /* CIRCLED IDEOGRAPH LOW */
+  {0x32a7, 1, 3085}, /* CIRCLED IDEOGRAPH LEFT */
+  {0x32a8, 1, 3086}, /* CIRCLED IDEOGRAPH RIGHT */
+  {0x32a9, 1, 3087}, /* CIRCLED IDEOGRAPH MEDICINE */
+  {0x32aa, 1, 3088}, /* CIRCLED IDEOGRAPH RELIGION */
+  {0x32ab, 1, 3016}, /* CIRCLED IDEOGRAPH STUDY */
+  {0x32ac, 1, 3019}, /* CIRCLED IDEOGRAPH SUPERVISE */
+  {0x32ad, 1, 3022}, /* CIRCLED IDEOGRAPH ENTERPRISE */
+  {0x32ae, 1, 3025}, /* CIRCLED IDEOGRAPH RESOURCE */
+  {0x32af, 1, 3028}, /* CIRCLED IDEOGRAPH ALLIANCE */
+  {0x32b0, 1, 3089}, /* CIRCLED IDEOGRAPH NIGHT */
+  {0x32b1, 2, 3090}, /* CIRCLED NUMBER THIRTY SIX */
+  {0x32b2, 2, 3092}, /* CIRCLED NUMBER THIRTY SEVEN */
+  {0x32b3, 2, 3094}, /* CIRCLED NUMBER THIRTY EIGHT */
+  {0x32b4, 2, 3096}, /* CIRCLED NUMBER THIRTY NINE */
+  {0x32b5, 2, 3098}, /* CIRCLED NUMBER FORTY */
+  {0x32b6, 2, 17}, /* CIRCLED NUMBER FORTY ONE */
+  {0x32b7, 2, 3048}, /* CIRCLED NUMBER FORTY TWO */
+  {0x32b8, 2, 3064}, /* CIRCLED NUMBER FORTY THREE */
+  {0x32b9, 2, 3100}, /* CIRCLED NUMBER FORTY FOUR */
+  {0x32ba, 2, 3102}, /* CIRCLED NUMBER FORTY FIVE */
+  {0x32bb, 2, 3104}, /* CIRCLED NUMBER FORTY SIX */
+  {0x32bc, 2, 3106}, /* CIRCLED NUMBER FORTY SEVEN */
+  {0x32bd, 2, 3108}, /* CIRCLED NUMBER FORTY EIGHT */
+  {0x32be, 2, 3110}, /* CIRCLED NUMBER FORTY NINE */
+  {0x32bf, 2, 3112}, /* CIRCLED NUMBER FIFTY */
+  {0x32c0, 2, 3114}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY */
+  {0x32c1, 2, 3116}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY */
+  {0x32c2, 2, 3118}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH */
+  {0x32c3, 2, 3120}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL */
+  {0x32c4, 2, 3122}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY */
+  {0x32c5, 2, 3124}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE */
+  {0x32c6, 2, 3126}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY */
+  {0x32c7, 2, 3128}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST */
+  {0x32c8, 2, 3130}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER */
+  {0x32c9, 3, 3132}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER */
+  {0x32ca, 3, 3135}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER */
+  {0x32cb, 3, 3138}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER */
+  {0x32cc, 2, 3141}, /* SQUARE HG */
+  {0x32cd, 3, 3143}, /* SQUARE ERG */
+  {0x32ce, 2, 3146}, /* SQUARE EV */
+  {0x32cf, 3, 3148}, /* LIMITED LIABILITY SIGN */
+  {0x32d0, 1, 3151}, /* CIRCLED KATAKANA A */
+  {0x32d1, 1, 3152}, /* CIRCLED KATAKANA I */
+  {0x32d2, 1, 2701}, /* CIRCLED KATAKANA U */
+  {0x32d3, 1, 3153}, /* CIRCLED KATAKANA E */
+  {0x32d4, 1, 3154}, /* CIRCLED KATAKANA O */
+  {0x32d5, 1, 2651}, /* CIRCLED KATAKANA KA */
+  {0x32d6, 1, 2653}, /* CIRCLED KATAKANA KI */
+  {0x32d7, 1, 2655}, /* CIRCLED KATAKANA KU */
+  {0x32d8, 1, 2657}, /* CIRCLED KATAKANA KE */
+  {0x32d9, 1, 2659}, /* CIRCLED KATAKANA KO */
+  {0x32da, 1, 2661}, /* CIRCLED KATAKANA SA */
+  {0x32db, 1, 2663}, /* CIRCLED KATAKANA SI */
+  {0x32dc, 1, 2665}, /* CIRCLED KATAKANA SU */
+  {0x32dd, 1, 2667}, /* CIRCLED KATAKANA SE */
+  {0x32de, 1, 2669}, /* CIRCLED KATAKANA SO */
+  {0x32df, 1, 2671}, /* CIRCLED KATAKANA TA */
+  {0x32e0, 1, 2673}, /* CIRCLED KATAKANA TI */
+  {0x32e1, 1, 2675}, /* CIRCLED KATAKANA TU */
+  {0x32e2, 1, 2677}, /* CIRCLED KATAKANA TE */
+  {0x32e3, 1, 2679}, /* CIRCLED KATAKANA TO */
+  {0x32e4, 1, 3155}, /* CIRCLED KATAKANA NA */
+  {0x32e5, 1, 3156}, /* CIRCLED KATAKANA NI */
+  {0x32e6, 1, 3157}, /* CIRCLED KATAKANA NU */
+  {0x32e7, 1, 3158}, /* CIRCLED KATAKANA NE */
+  {0x32e8, 1, 3159}, /* CIRCLED KATAKANA NO */
+  {0x32e9, 1, 2681}, /* CIRCLED KATAKANA HA */
+  {0x32ea, 1, 2685}, /* CIRCLED KATAKANA HI */
+  {0x32eb, 1, 2689}, /* CIRCLED KATAKANA HU */
+  {0x32ec, 1, 2693}, /* CIRCLED KATAKANA HE */
+  {0x32ed, 1, 2697}, /* CIRCLED KATAKANA HO */
+  {0x32ee, 1, 3160}, /* CIRCLED KATAKANA MA */
+  {0x32ef, 1, 3161}, /* CIRCLED KATAKANA MI */
+  {0x32f0, 1, 3162}, /* CIRCLED KATAKANA MU */
+  {0x32f1, 1, 3163}, /* CIRCLED KATAKANA ME */
+  {0x32f2, 1, 3164}, /* CIRCLED KATAKANA MO */
+  {0x32f3, 1, 3165}, /* CIRCLED KATAKANA YA */
+  {0x32f4, 1, 3166}, /* CIRCLED KATAKANA YU */
+  {0x32f5, 1, 3167}, /* CIRCLED KATAKANA YO */
+  {0x32f6, 1, 3168}, /* CIRCLED KATAKANA RA */
+  {0x32f7, 1, 3169}, /* CIRCLED KATAKANA RI */
+  {0x32f8, 1, 3170}, /* CIRCLED KATAKANA RU */
+  {0x32f9, 1, 3171}, /* CIRCLED KATAKANA RE */
+  {0x32fa, 1, 3172}, /* CIRCLED KATAKANA RO */
+  {0x32fb, 1, 2703}, /* CIRCLED KATAKANA WA */
+  {0x32fc, 1, 2705}, /* CIRCLED KATAKANA WI */
+  {0x32fd, 1, 2707}, /* CIRCLED KATAKANA WE */
+  {0x32fe, 1, 2709}, /* CIRCLED KATAKANA WO */
+  {0x3300, 4, 3173}, /* SQUARE APAATO */
+  {0x3301, 4, 3177}, /* SQUARE ARUHUA */
+  {0x3302, 4, 3181}, /* SQUARE ANPEA */
+  {0x3303, 3, 3185}, /* SQUARE AARU */
+  {0x3304, 4, 3188}, /* SQUARE ININGU */
+  {0x3305, 3, 3192}, /* SQUARE INTI */
+  {0x3306, 3, 3195}, /* SQUARE UON */
+  {0x3307, 5, 3198}, /* SQUARE ESUKUUDO */
+  {0x3308, 4, 3203}, /* SQUARE EEKAA */
+  {0x3309, 3, 3207}, /* SQUARE ONSU */
+  {0x330a, 3, 3210}, /* SQUARE OOMU */
+  {0x330b, 3, 3213}, /* SQUARE KAIRI */
+  {0x330c, 4, 3216}, /* SQUARE KARATTO */
+  {0x330d, 4, 3220}, /* SQUARE KARORII */
+  {0x330e, 3, 3224}, /* SQUARE GARON */
+  {0x330f, 3, 3227}, /* SQUARE GANMA */
+  {0x3310, 2, 3230}, /* SQUARE GIGA */
+  {0x3311, 3, 3232}, /* SQUARE GINII */
+  {0x3312, 4, 3235}, /* SQUARE KYURII */
+  {0x3313, 4, 3239}, /* SQUARE GIRUDAA */
+  {0x3314, 2, 3243}, /* SQUARE KIRO */
+  {0x3315, 5, 3245}, /* SQUARE KIROGURAMU */
+  {0x3316, 6, 3250}, /* SQUARE KIROMEETORU */
+  {0x3317, 5, 3256}, /* SQUARE KIROWATTO */
+  {0x3318, 3, 3247}, /* SQUARE GURAMU */
+  {0x3319, 5, 3261}, /* SQUARE GURAMUTON */
+  {0x331a, 5, 3266}, /* SQUARE KURUZEIRO */
+  {0x331b, 4, 3271}, /* SQUARE KUROONE */
+  {0x331c, 3, 3275}, /* SQUARE KEESU */
+  {0x331d, 3, 3278}, /* SQUARE KORUNA */
+  {0x331e, 3, 3281}, /* SQUARE KOOPO */
+  {0x331f, 4, 3284}, /* SQUARE SAIKURU */
+  {0x3320, 5, 3288}, /* SQUARE SANTIIMU */
+  {0x3321, 4, 3293}, /* SQUARE SIRINGU */
+  {0x3322, 3, 3297}, /* SQUARE SENTI */
+  {0x3323, 3, 3300}, /* SQUARE SENTO */
+  {0x3324, 3, 3303}, /* SQUARE DAASU */
+  {0x3325, 2, 3306}, /* SQUARE DESI */
+  {0x3326, 2, 3308}, /* SQUARE DORU */
+  {0x3327, 2, 3264}, /* SQUARE TON */
+  {0x3328, 2, 3310}, /* SQUARE NANO */
+  {0x3329, 3, 3312}, /* SQUARE NOTTO */
+  {0x332a, 3, 3315}, /* SQUARE HAITU */
+  {0x332b, 5, 3318}, /* SQUARE PAASENTO */
+  {0x332c, 3, 3323}, /* SQUARE PAATU */
+  {0x332d, 4, 3326}, /* SQUARE BAARERU */
+  {0x332e, 5, 3330}, /* SQUARE PIASUTORU */
+  {0x332f, 3, 3335}, /* SQUARE PIKURU */
+  {0x3330, 2, 3338}, /* SQUARE PIKO */
+  {0x3331, 2, 3340}, /* SQUARE BIRU */
+  {0x3332, 5, 3342}, /* SQUARE HUARADDO */
+  {0x3333, 4, 3347}, /* SQUARE HUIITO */
+  {0x3334, 5, 3351}, /* SQUARE BUSSYERU */
+  {0x3335, 3, 3356}, /* SQUARE HURAN */
+  {0x3336, 5, 3359}, /* SQUARE HEKUTAARU */
+  {0x3337, 2, 3364}, /* SQUARE PESO */
+  {0x3338, 3, 3366}, /* SQUARE PENIHI */
+  {0x3339, 3, 3369}, /* SQUARE HERUTU */
+  {0x333a, 3, 3372}, /* SQUARE PENSU */
+  {0x333b, 3, 3375}, /* SQUARE PEEZI */
+  {0x333c, 3, 3378}, /* SQUARE BEETA */
+  {0x333d, 4, 3381}, /* SQUARE POINTO */
+  {0x333e, 3, 3385}, /* SQUARE BORUTO */
+  {0x333f, 2, 3388}, /* SQUARE HON */
+  {0x3340, 3, 3390}, /* SQUARE PONDO */
+  {0x3341, 3, 3393}, /* SQUARE HOORU */
+  {0x3342, 3, 3396}, /* SQUARE HOON */
+  {0x3343, 4, 3399}, /* SQUARE MAIKURO */
+  {0x3344, 3, 3403}, /* SQUARE MAIRU */
+  {0x3345, 3, 3406}, /* SQUARE MAHHA */
+  {0x3346, 3, 3409}, /* SQUARE MARUKU */
+  {0x3347, 5, 3412}, /* SQUARE MANSYON */
+  {0x3348, 4, 3417}, /* SQUARE MIKURON */
+  {0x3349, 2, 3421}, /* SQUARE MIRI */
+  {0x334a, 5, 3423}, /* SQUARE MIRIBAARU */
+  {0x334b, 2, 3428}, /* SQUARE MEGA */
+  {0x334c, 4, 3430}, /* SQUARE MEGATON */
+  {0x334d, 4, 3252}, /* SQUARE MEETORU */
+  {0x334e, 3, 3434}, /* SQUARE YAADO */
+  {0x334f, 3, 3437}, /* SQUARE YAARU */
+  {0x3350, 3, 3440}, /* SQUARE YUAN */
+  {0x3351, 4, 3443}, /* SQUARE RITTORU */
+  {0x3352, 2, 3447}, /* SQUARE RIRA */
+  {0x3353, 3, 3449}, /* SQUARE RUPII */
+  {0x3354, 4, 3452}, /* SQUARE RUUBURU */
+  {0x3355, 2, 3456}, /* SQUARE REMU */
+  {0x3356, 5, 3458}, /* SQUARE RENTOGEN */
+  {0x3357, 3, 3258}, /* SQUARE WATTO */
+  {0x3358, 2, 3463}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO */
+  {0x3359, 2, 3465}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE */
+  {0x335a, 2, 3467}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO */
+  {0x335b, 2, 3469}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE */
+  {0x335c, 2, 3471}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR */
+  {0x335d, 2, 3473}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE */
+  {0x335e, 2, 3475}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX */
+  {0x335f, 2, 3477}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN */
+  {0x3360, 2, 3479}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT */
+  {0x3361, 2, 3481}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE */
+  {0x3362, 3, 3483}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN */
+  {0x3363, 3, 3486}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN */
+  {0x3364, 3, 3489}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE */
+  {0x3365, 3, 3492}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN */
+  {0x3366, 3, 3495}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN */
+  {0x3367, 3, 3498}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN */
+  {0x3368, 3, 3501}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN */
+  {0x3369, 3, 3504}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN */
+  {0x336a, 3, 3507}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN */
+  {0x336b, 3, 3510}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN */
+  {0x336c, 3, 3513}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY */
+  {0x336d, 3, 3516}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE */
+  {0x336e, 3, 3519}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO */
+  {0x336f, 3, 3522}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE */
+  {0x3370, 3, 3525}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR */
+  {0x3371, 3, 3528}, /* SQUARE HPA */
+  {0x3372, 2, 3531}, /* SQUARE DA */
+  {0x3373, 2, 3533}, /* SQUARE AU */
+  {0x3374, 3, 3535}, /* SQUARE BAR */
+  {0x3375, 2, 3538}, /* SQUARE OV */
+  {0x3376, 2, 3540}, /* SQUARE PC */
+  {0x3377, 2, 3542}, /* SQUARE DM */
+  {0x3378, 3, 3544}, /* SQUARE DM SQUARED */
+  {0x3379, 3, 3547}, /* SQUARE DM CUBED */
+  {0x337a, 2, 3550}, /* SQUARE IU */
+  {0x337b, 2, 3552}, /* SQUARE ERA NAME HEISEI */
+  {0x337c, 2, 3554}, /* SQUARE ERA NAME SYOUWA */
+  {0x337d, 2, 3556}, /* SQUARE ERA NAME TAISYOU */
+  {0x337e, 2, 3558}, /* SQUARE ERA NAME MEIZI */
+  {0x337f, 4, 3560}, /* SQUARE CORPORATION */
+  {0x3380, 2, 3564}, /* SQUARE PA AMPS */
+  {0x3381, 2, 3566}, /* SQUARE NA */
+  {0x3382, 2, 3568}, /* SQUARE MU A */
+  {0x3383, 2, 3570}, /* SQUARE MA */
+  {0x3384, 2, 3572}, /* SQUARE KA */
+  {0x3385, 2, 3574}, /* SQUARE KB */
+  {0x3386, 2, 3576}, /* SQUARE MB */
+  {0x3387, 2, 3578}, /* SQUARE GB */
+  {0x3388, 3, 3580}, /* SQUARE CAL */
+  {0x3389, 4, 3583}, /* SQUARE KCAL */
+  {0x338a, 2, 3587}, /* SQUARE PF */
+  {0x338b, 2, 3589}, /* SQUARE NF */
+  {0x338c, 2, 3591}, /* SQUARE MU F */
+  {0x338d, 2, 3593}, /* SQUARE MU G */
+  {0x338e, 2, 3595}, /* SQUARE MG */
+  {0x338f, 2, 3597}, /* SQUARE KG */
+  {0x3390, 2, 3599}, /* SQUARE HZ */
+  {0x3391, 3, 3601}, /* SQUARE KHZ */
+  {0x3392, 3, 3604}, /* SQUARE MHZ */
+  {0x3393, 3, 3607}, /* SQUARE GHZ */
+  {0x3394, 3, 3610}, /* SQUARE THZ */
+  {0x3395, 2, 3613}, /* SQUARE MU L */
+  {0x3396, 2, 3615}, /* SQUARE ML */
+  {0x3397, 2, 3617}, /* SQUARE DL */
+  {0x3398, 2, 3619}, /* SQUARE KL */
+  {0x3399, 2, 3621}, /* SQUARE FM */
+  {0x339a, 2, 3623}, /* SQUARE NM */
+  {0x339b, 2, 3625}, /* SQUARE MU M */
+  {0x339c, 2, 3627}, /* SQUARE MM */
+  {0x339d, 2, 3629}, /* SQUARE CM */
+  {0x339e, 2, 3631}, /* SQUARE KM */
+  {0x339f, 3, 3633}, /* SQUARE MM SQUARED */
+  {0x33a0, 3, 3636}, /* SQUARE CM SQUARED */
+  {0x33a1, 2, 3545}, /* SQUARE M SQUARED */
+  {0x33a2, 3, 3639}, /* SQUARE KM SQUARED */
+  {0x33a3, 3, 3642}, /* SQUARE MM CUBED */
+  {0x33a4, 3, 3645}, /* SQUARE CM CUBED */
+  {0x33a5, 2, 3548}, /* SQUARE M CUBED */
+  {0x33a6, 3, 3648}, /* SQUARE KM CUBED */
+  {0x33a7, 3, 3651}, /* SQUARE M OVER S */
+  {0x33a8, 4, 3654}, /* SQUARE M OVER S SQUARED */
+  {0x33a9, 2, 3529}, /* SQUARE PA */
+  {0x33aa, 3, 3658}, /* SQUARE KPA */
+  {0x33ab, 3, 3661}, /* SQUARE MPA */
+  {0x33ac, 3, 3664}, /* SQUARE GPA */
+  {0x33ad, 3, 3667}, /* SQUARE RAD */
+  {0x33ae, 5, 3670}, /* SQUARE RAD OVER S */
+  {0x33af, 6, 3675}, /* SQUARE RAD OVER S SQUARED */
+  {0x33b0, 2, 3681}, /* SQUARE PS */
+  {0x33b1, 2, 3683}, /* SQUARE NS */
+  {0x33b2, 2, 3685}, /* SQUARE MU S */
+  {0x33b3, 2, 3687}, /* SQUARE MS */
+  {0x33b4, 2, 3689}, /* SQUARE PV */
+  {0x33b5, 2, 3691}, /* SQUARE NV */
+  {0x33b6, 2, 3693}, /* SQUARE MU V */
+  {0x33b7, 2, 3695}, /* SQUARE MV */
+  {0x33b8, 2, 3697}, /* SQUARE KV */
+  {0x33b9, 2, 3699}, /* SQUARE MV MEGA */
+  {0x33ba, 2, 3701}, /* SQUARE PW */
+  {0x33bb, 2, 3703}, /* SQUARE NW */
+  {0x33bc, 2, 3705}, /* SQUARE MU W */
+  {0x33bd, 2, 3707}, /* SQUARE MW */
+  {0x33be, 2, 3709}, /* SQUARE KW */
+  {0x33bf, 2, 3711}, /* SQUARE MW MEGA */
+  {0x33c0, 2, 3713}, /* SQUARE K OHM */
+  {0x33c1, 2, 3715}, /* SQUARE M OHM */
+  {0x33c2, 4, 3717}, /* SQUARE AM */
+  {0x33c3, 2, 3721}, /* SQUARE BQ */
+  {0x33c4, 2, 3723}, /* SQUARE CC */
+  {0x33c5, 2, 3541}, /* SQUARE CD */
+  {0x33c6, 4, 3725}, /* SQUARE C OVER KG */
+  {0x33c7, 3, 3729}, /* SQUARE CO */
+  {0x33c8, 2, 3732}, /* SQUARE DB */
+  {0x33c9, 2, 3734}, /* SQUARE GY */
+  {0x33ca, 2, 3736}, /* SQUARE HA */
+  {0x33cb, 2, 3738}, /* SQUARE HP */
+  {0x33cc, 2, 3740}, /* SQUARE IN */
+  {0x33cd, 2, 3742}, /* SQUARE KK */
+  {0x33ce, 2, 3744}, /* SQUARE KM CAPITAL */
+  {0x33cf, 2, 3746}, /* SQUARE KT */
+  {0x33d0, 2, 3748}, /* SQUARE LM */
+  {0x33d1, 2, 3750}, /* SQUARE LN */
+  {0x33d2, 3, 3752}, /* SQUARE LOG */
+  {0x33d3, 2, 3755}, /* SQUARE LX */
+  {0x33d4, 2, 3757}, /* SQUARE MB SMALL */
+  {0x33d5, 3, 3759}, /* SQUARE MIL */
+  {0x33d6, 3, 3762}, /* SQUARE MOL */
+  {0x33d7, 2, 3765}, /* SQUARE PH */
+  {0x33d8, 4, 3767}, /* SQUARE PM */
+  {0x33d9, 3, 3771}, /* SQUARE PPM */
+  {0x33da, 2, 3774}, /* SQUARE PR */
+  {0x33db, 2, 3674}, /* SQUARE SR */
+  {0x33dc, 2, 3776}, /* SQUARE SV */
+  {0x33dd, 2, 3778}, /* SQUARE WB */
+  {0x33de, 3, 3780}, /* SQUARE V OVER M */
+  {0x33df, 3, 3783}, /* SQUARE A OVER M */
+  {0x33e0, 2, 3786}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE */
+  {0x33e1, 2, 3788}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO */
+  {0x33e2, 2, 3790}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE */
+  {0x33e3, 2, 3792}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR */
+  {0x33e4, 2, 3794}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE */
+  {0x33e5, 2, 3796}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX */
+  {0x33e6, 2, 3798}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN */
+  {0x33e7, 2, 3800}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT */
+  {0x33e8, 2, 3802}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE */
+  {0x33e9, 3, 3804}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN */
+  {0x33ea, 3, 3807}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN */
+  {0x33eb, 3, 3810}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE */
+  {0x33ec, 3, 3813}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN */
+  {0x33ed, 3, 3816}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN */
+  {0x33ee, 3, 3819}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN */
+  {0x33ef, 3, 3822}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN */
+  {0x33f0, 3, 3825}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN */
+  {0x33f1, 3, 3828}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN */
+  {0x33f2, 3, 3831}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN */
+  {0x33f3, 3, 3834}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY */
+  {0x33f4, 3, 3837}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE */
+  {0x33f5, 3, 3840}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO */
+  {0x33f6, 3, 3843}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE */
+  {0x33f7, 3, 3846}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR */
+  {0x33f8, 3, 3849}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE */
+  {0x33f9, 3, 3852}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX */
+  {0x33fa, 3, 3855}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN */
+  {0x33fb, 3, 3858}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT */
+  {0x33fc, 3, 3861}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE */
+  {0x33fd, 3, 3864}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY */
+  {0x33fe, 3, 3867}, /* IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE */
+  {0x33ff, 3, 3870}, /* SQUARE GAL */
+  {0xf900, 1, 3873}, /* CJK COMPATIBILITY IDEOGRAPH-F900 */
+  {0xf901, 1, 3874}, /* CJK COMPATIBILITY IDEOGRAPH-F901 */
+  {0xf902, 1, 2531}, /* CJK COMPATIBILITY IDEOGRAPH-F902 */
+  {0xf903, 1, 3875}, /* CJK COMPATIBILITY IDEOGRAPH-F903 */
+  {0xf904, 1, 3876}, /* CJK COMPATIBILITY IDEOGRAPH-F904 */
+  {0xf905, 1, 3877}, /* CJK COMPATIBILITY IDEOGRAPH-F905 */
+  {0xf906, 1, 3878}, /* CJK COMPATIBILITY IDEOGRAPH-F906 */
+  {0xf907, 1, 2585}, /* CJK COMPATIBILITY IDEOGRAPH-F907 */
+  {0xf908, 1, 2585}, /* CJK COMPATIBILITY IDEOGRAPH-F908 */
+  {0xf909, 1, 3879}, /* CJK COMPATIBILITY IDEOGRAPH-F909 */
+  {0xf90a, 1, 2539}, /* CJK COMPATIBILITY IDEOGRAPH-F90A */
+  {0xf90b, 1, 3880}, /* CJK COMPATIBILITY IDEOGRAPH-F90B */
+  {0xf90c, 1, 3881}, /* CJK COMPATIBILITY IDEOGRAPH-F90C */
+  {0xf90d, 1, 3882}, /* CJK COMPATIBILITY IDEOGRAPH-F90D */
+  {0xf90e, 1, 3883}, /* CJK COMPATIBILITY IDEOGRAPH-F90E */
+  {0xf90f, 1, 3884}, /* CJK COMPATIBILITY IDEOGRAPH-F90F */
+  {0xf910, 1, 3885}, /* CJK COMPATIBILITY IDEOGRAPH-F910 */
+  {0xf911, 1, 3886}, /* CJK COMPATIBILITY IDEOGRAPH-F911 */
+  {0xf912, 1, 3887}, /* CJK COMPATIBILITY IDEOGRAPH-F912 */
+  {0xf913, 1, 3888}, /* CJK COMPATIBILITY IDEOGRAPH-F913 */
+  {0xf914, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F914 */
+  {0xf915, 1, 3890}, /* CJK COMPATIBILITY IDEOGRAPH-F915 */
+  {0xf916, 1, 3891}, /* CJK COMPATIBILITY IDEOGRAPH-F916 */
+  {0xf917, 1, 3892}, /* CJK COMPATIBILITY IDEOGRAPH-F917 */
+  {0xf918, 1, 3893}, /* CJK COMPATIBILITY IDEOGRAPH-F918 */
+  {0xf919, 1, 3894}, /* CJK COMPATIBILITY IDEOGRAPH-F919 */
+  {0xf91a, 1, 3895}, /* CJK COMPATIBILITY IDEOGRAPH-F91A */
+  {0xf91b, 1, 3896}, /* CJK COMPATIBILITY IDEOGRAPH-F91B */
+  {0xf91c, 1, 3897}, /* CJK COMPATIBILITY IDEOGRAPH-F91C */
+  {0xf91d, 1, 3898}, /* CJK COMPATIBILITY IDEOGRAPH-F91D */
+  {0xf91e, 1, 3899}, /* CJK COMPATIBILITY IDEOGRAPH-F91E */
+  {0xf91f, 1, 3900}, /* CJK COMPATIBILITY IDEOGRAPH-F91F */
+  {0xf920, 1, 3901}, /* CJK COMPATIBILITY IDEOGRAPH-F920 */
+  {0xf921, 1, 3902}, /* CJK COMPATIBILITY IDEOGRAPH-F921 */
+  {0xf922, 1, 3903}, /* CJK COMPATIBILITY IDEOGRAPH-F922 */
+  {0xf923, 1, 3904}, /* CJK COMPATIBILITY IDEOGRAPH-F923 */
+  {0xf924, 1, 3905}, /* CJK COMPATIBILITY IDEOGRAPH-F924 */
+  {0xf925, 1, 3906}, /* CJK COMPATIBILITY IDEOGRAPH-F925 */
+  {0xf926, 1, 3907}, /* CJK COMPATIBILITY IDEOGRAPH-F926 */
+  {0xf927, 1, 3908}, /* CJK COMPATIBILITY IDEOGRAPH-F927 */
+  {0xf928, 1, 3909}, /* CJK COMPATIBILITY IDEOGRAPH-F928 */
+  {0xf929, 1, 3910}, /* CJK COMPATIBILITY IDEOGRAPH-F929 */
+  {0xf92a, 1, 3911}, /* CJK COMPATIBILITY IDEOGRAPH-F92A */
+  {0xf92b, 1, 3912}, /* CJK COMPATIBILITY IDEOGRAPH-F92B */
+  {0xf92c, 1, 3913}, /* CJK COMPATIBILITY IDEOGRAPH-F92C */
+  {0xf92d, 1, 3914}, /* CJK COMPATIBILITY IDEOGRAPH-F92D */
+  {0xf92e, 1, 3915}, /* CJK COMPATIBILITY IDEOGRAPH-F92E */
+  {0xf92f, 1, 3916}, /* CJK COMPATIBILITY IDEOGRAPH-F92F */
+  {0xf930, 1, 3917}, /* CJK COMPATIBILITY IDEOGRAPH-F930 */
+  {0xf931, 1, 3918}, /* CJK COMPATIBILITY IDEOGRAPH-F931 */
+  {0xf932, 1, 3919}, /* CJK COMPATIBILITY IDEOGRAPH-F932 */
+  {0xf933, 1, 3920}, /* CJK COMPATIBILITY IDEOGRAPH-F933 */
+  {0xf934, 1, 2497}, /* CJK COMPATIBILITY IDEOGRAPH-F934 */
+  {0xf935, 1, 3921}, /* CJK COMPATIBILITY IDEOGRAPH-F935 */
+  {0xf936, 1, 3922}, /* CJK COMPATIBILITY IDEOGRAPH-F936 */
+  {0xf937, 1, 3923}, /* CJK COMPATIBILITY IDEOGRAPH-F937 */
+  {0xf938, 1, 3924}, /* CJK COMPATIBILITY IDEOGRAPH-F938 */
+  {0xf939, 1, 3925}, /* CJK COMPATIBILITY IDEOGRAPH-F939 */
+  {0xf93a, 1, 3926}, /* CJK COMPATIBILITY IDEOGRAPH-F93A */
+  {0xf93b, 1, 3927}, /* CJK COMPATIBILITY IDEOGRAPH-F93B */
+  {0xf93c, 1, 3928}, /* CJK COMPATIBILITY IDEOGRAPH-F93C */
+  {0xf93d, 1, 3929}, /* CJK COMPATIBILITY IDEOGRAPH-F93D */
+  {0xf93e, 1, 3930}, /* CJK COMPATIBILITY IDEOGRAPH-F93E */
+  {0xf93f, 1, 3931}, /* CJK COMPATIBILITY IDEOGRAPH-F93F */
+  {0xf940, 1, 2570}, /* CJK COMPATIBILITY IDEOGRAPH-F940 */
+  {0xf941, 1, 3932}, /* CJK COMPATIBILITY IDEOGRAPH-F941 */
+  {0xf942, 1, 3933}, /* CJK COMPATIBILITY IDEOGRAPH-F942 */
+  {0xf943, 1, 3934}, /* CJK COMPATIBILITY IDEOGRAPH-F943 */
+  {0xf944, 1, 3935}, /* CJK COMPATIBILITY IDEOGRAPH-F944 */
+  {0xf945, 1, 3936}, /* CJK COMPATIBILITY IDEOGRAPH-F945 */
+  {0xf946, 1, 3937}, /* CJK COMPATIBILITY IDEOGRAPH-F946 */
+  {0xf947, 1, 3938}, /* CJK COMPATIBILITY IDEOGRAPH-F947 */
+  {0xf948, 1, 3939}, /* CJK COMPATIBILITY IDEOGRAPH-F948 */
+  {0xf949, 1, 3940}, /* CJK COMPATIBILITY IDEOGRAPH-F949 */
+  {0xf94a, 1, 3941}, /* CJK COMPATIBILITY IDEOGRAPH-F94A */
+  {0xf94b, 1, 3942}, /* CJK COMPATIBILITY IDEOGRAPH-F94B */
+  {0xf94c, 1, 3943}, /* CJK COMPATIBILITY IDEOGRAPH-F94C */
+  {0xf94d, 1, 3944}, /* CJK COMPATIBILITY IDEOGRAPH-F94D */
+  {0xf94e, 1, 3945}, /* CJK COMPATIBILITY IDEOGRAPH-F94E */
+  {0xf94f, 1, 3946}, /* CJK COMPATIBILITY IDEOGRAPH-F94F */
+  {0xf950, 1, 3947}, /* CJK COMPATIBILITY IDEOGRAPH-F950 */
+  {0xf951, 1, 3948}, /* CJK COMPATIBILITY IDEOGRAPH-F951 */
+  {0xf952, 1, 3949}, /* CJK COMPATIBILITY IDEOGRAPH-F952 */
+  {0xf953, 1, 3950}, /* CJK COMPATIBILITY IDEOGRAPH-F953 */
+  {0xf954, 1, 3951}, /* CJK COMPATIBILITY IDEOGRAPH-F954 */
+  {0xf955, 1, 3952}, /* CJK COMPATIBILITY IDEOGRAPH-F955 */
+  {0xf956, 1, 3953}, /* CJK COMPATIBILITY IDEOGRAPH-F956 */
+  {0xf957, 1, 3954}, /* CJK COMPATIBILITY IDEOGRAPH-F957 */
+  {0xf958, 1, 3955}, /* CJK COMPATIBILITY IDEOGRAPH-F958 */
+  {0xf959, 1, 3956}, /* CJK COMPATIBILITY IDEOGRAPH-F959 */
+  {0xf95a, 1, 3957}, /* CJK COMPATIBILITY IDEOGRAPH-F95A */
+  {0xf95b, 1, 3958}, /* CJK COMPATIBILITY IDEOGRAPH-F95B */
+  {0xf95c, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F95C */
+  {0xf95d, 1, 3959}, /* CJK COMPATIBILITY IDEOGRAPH-F95D */
+  {0xf95e, 1, 3960}, /* CJK COMPATIBILITY IDEOGRAPH-F95E */
+  {0xf95f, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-F95F */
+  {0xf960, 1, 3962}, /* CJK COMPATIBILITY IDEOGRAPH-F960 */
+  {0xf961, 1, 3963}, /* CJK COMPATIBILITY IDEOGRAPH-F961 */
+  {0xf962, 1, 3964}, /* CJK COMPATIBILITY IDEOGRAPH-F962 */
+  {0xf963, 1, 3965}, /* CJK COMPATIBILITY IDEOGRAPH-F963 */
+  {0xf964, 1, 3966}, /* CJK COMPATIBILITY IDEOGRAPH-F964 */
+  {0xf965, 1, 3967}, /* CJK COMPATIBILITY IDEOGRAPH-F965 */
+  {0xf966, 1, 3968}, /* CJK COMPATIBILITY IDEOGRAPH-F966 */
+  {0xf967, 1, 3969}, /* CJK COMPATIBILITY IDEOGRAPH-F967 */
+  {0xf968, 1, 3970}, /* CJK COMPATIBILITY IDEOGRAPH-F968 */
+  {0xf969, 1, 3971}, /* CJK COMPATIBILITY IDEOGRAPH-F969 */
+  {0xf96a, 1, 3972}, /* CJK COMPATIBILITY IDEOGRAPH-F96A */
+  {0xf96b, 1, 3973}, /* CJK COMPATIBILITY IDEOGRAPH-F96B */
+  {0xf96c, 1, 3974}, /* CJK COMPATIBILITY IDEOGRAPH-F96C */
+  {0xf96d, 1, 3975}, /* CJK COMPATIBILITY IDEOGRAPH-F96D */
+  {0xf96e, 1, 3976}, /* CJK COMPATIBILITY IDEOGRAPH-F96E */
+  {0xf96f, 1, 3977}, /* CJK COMPATIBILITY IDEOGRAPH-F96F */
+  {0xf970, 1, 3978}, /* CJK COMPATIBILITY IDEOGRAPH-F970 */
+  {0xf971, 1, 2533}, /* CJK COMPATIBILITY IDEOGRAPH-F971 */
+  {0xf972, 1, 3979}, /* CJK COMPATIBILITY IDEOGRAPH-F972 */
+  {0xf973, 1, 3980}, /* CJK COMPATIBILITY IDEOGRAPH-F973 */
+  {0xf974, 1, 3981}, /* CJK COMPATIBILITY IDEOGRAPH-F974 */
+  {0xf975, 1, 3982}, /* CJK COMPATIBILITY IDEOGRAPH-F975 */
+  {0xf976, 1, 3983}, /* CJK COMPATIBILITY IDEOGRAPH-F976 */
+  {0xf977, 1, 3984}, /* CJK COMPATIBILITY IDEOGRAPH-F977 */
+  {0xf978, 1, 3985}, /* CJK COMPATIBILITY IDEOGRAPH-F978 */
+  {0xf979, 1, 3986}, /* CJK COMPATIBILITY IDEOGRAPH-F979 */
+  {0xf97a, 1, 3987}, /* CJK COMPATIBILITY IDEOGRAPH-F97A */
+  {0xf97b, 1, 3988}, /* CJK COMPATIBILITY IDEOGRAPH-F97B */
+  {0xf97c, 1, 3989}, /* CJK COMPATIBILITY IDEOGRAPH-F97C */
+  {0xf97d, 1, 3990}, /* CJK COMPATIBILITY IDEOGRAPH-F97D */
+  {0xf97e, 1, 3991}, /* CJK COMPATIBILITY IDEOGRAPH-F97E */
+  {0xf97f, 1, 3992}, /* CJK COMPATIBILITY IDEOGRAPH-F97F */
+  {0xf980, 1, 3993}, /* CJK COMPATIBILITY IDEOGRAPH-F980 */
+  {0xf981, 1, 2410}, /* CJK COMPATIBILITY IDEOGRAPH-F981 */
+  {0xf982, 1, 3994}, /* CJK COMPATIBILITY IDEOGRAPH-F982 */
+  {0xf983, 1, 3995}, /* CJK COMPATIBILITY IDEOGRAPH-F983 */
+  {0xf984, 1, 3996}, /* CJK COMPATIBILITY IDEOGRAPH-F984 */
+  {0xf985, 1, 3997}, /* CJK COMPATIBILITY IDEOGRAPH-F985 */
+  {0xf986, 1, 3998}, /* CJK COMPATIBILITY IDEOGRAPH-F986 */
+  {0xf987, 1, 3999}, /* CJK COMPATIBILITY IDEOGRAPH-F987 */
+  {0xf988, 1, 4000}, /* CJK COMPATIBILITY IDEOGRAPH-F988 */
+  {0xf989, 1, 4001}, /* CJK COMPATIBILITY IDEOGRAPH-F989 */
+  {0xf98a, 1, 2391}, /* CJK COMPATIBILITY IDEOGRAPH-F98A */
+  {0xf98b, 1, 4002}, /* CJK COMPATIBILITY IDEOGRAPH-F98B */
+  {0xf98c, 1, 4003}, /* CJK COMPATIBILITY IDEOGRAPH-F98C */
+  {0xf98d, 1, 4004}, /* CJK COMPATIBILITY IDEOGRAPH-F98D */
+  {0xf98e, 1, 4005}, /* CJK COMPATIBILITY IDEOGRAPH-F98E */
+  {0xf98f, 1, 4006}, /* CJK COMPATIBILITY IDEOGRAPH-F98F */
+  {0xf990, 1, 4007}, /* CJK COMPATIBILITY IDEOGRAPH-F990 */
+  {0xf991, 1, 4008}, /* CJK COMPATIBILITY IDEOGRAPH-F991 */
+  {0xf992, 1, 4009}, /* CJK COMPATIBILITY IDEOGRAPH-F992 */
+  {0xf993, 1, 4010}, /* CJK COMPATIBILITY IDEOGRAPH-F993 */
+  {0xf994, 1, 4011}, /* CJK COMPATIBILITY IDEOGRAPH-F994 */
+  {0xf995, 1, 4012}, /* CJK COMPATIBILITY IDEOGRAPH-F995 */
+  {0xf996, 1, 4013}, /* CJK COMPATIBILITY IDEOGRAPH-F996 */
+  {0xf997, 1, 4014}, /* CJK COMPATIBILITY IDEOGRAPH-F997 */
+  {0xf998, 1, 4015}, /* CJK COMPATIBILITY IDEOGRAPH-F998 */
+  {0xf999, 1, 4016}, /* CJK COMPATIBILITY IDEOGRAPH-F999 */
+  {0xf99a, 1, 4017}, /* CJK COMPATIBILITY IDEOGRAPH-F99A */
+  {0xf99b, 1, 4018}, /* CJK COMPATIBILITY IDEOGRAPH-F99B */
+  {0xf99c, 1, 4019}, /* CJK COMPATIBILITY IDEOGRAPH-F99C */
+  {0xf99d, 1, 4020}, /* CJK COMPATIBILITY IDEOGRAPH-F99D */
+  {0xf99e, 1, 4021}, /* CJK COMPATIBILITY IDEOGRAPH-F99E */
+  {0xf99f, 1, 4022}, /* CJK COMPATIBILITY IDEOGRAPH-F99F */
+  {0xf9a0, 1, 4023}, /* CJK COMPATIBILITY IDEOGRAPH-F9A0 */
+  {0xf9a1, 1, 3977}, /* CJK COMPATIBILITY IDEOGRAPH-F9A1 */
+  {0xf9a2, 1, 4024}, /* CJK COMPATIBILITY IDEOGRAPH-F9A2 */
+  {0xf9a3, 1, 4025}, /* CJK COMPATIBILITY IDEOGRAPH-F9A3 */
+  {0xf9a4, 1, 4026}, /* CJK COMPATIBILITY IDEOGRAPH-F9A4 */
+  {0xf9a5, 1, 4027}, /* CJK COMPATIBILITY IDEOGRAPH-F9A5 */
+  {0xf9a6, 1, 4028}, /* CJK COMPATIBILITY IDEOGRAPH-F9A6 */
+  {0xf9a7, 1, 4029}, /* CJK COMPATIBILITY IDEOGRAPH-F9A7 */
+  {0xf9a8, 1, 4030}, /* CJK COMPATIBILITY IDEOGRAPH-F9A8 */
+  {0xf9a9, 1, 4031}, /* CJK COMPATIBILITY IDEOGRAPH-F9A9 */
+  {0xf9aa, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-F9AA */
+  {0xf9ab, 1, 4032}, /* CJK COMPATIBILITY IDEOGRAPH-F9AB */
+  {0xf9ac, 1, 4033}, /* CJK COMPATIBILITY IDEOGRAPH-F9AC */
+  {0xf9ad, 1, 4034}, /* CJK COMPATIBILITY IDEOGRAPH-F9AD */
+  {0xf9ae, 1, 4035}, /* CJK COMPATIBILITY IDEOGRAPH-F9AE */
+  {0xf9af, 1, 4036}, /* CJK COMPATIBILITY IDEOGRAPH-F9AF */
+  {0xf9b0, 1, 4037}, /* CJK COMPATIBILITY IDEOGRAPH-F9B0 */
+  {0xf9b1, 1, 4038}, /* CJK COMPATIBILITY IDEOGRAPH-F9B1 */
+  {0xf9b2, 1, 4039}, /* CJK COMPATIBILITY IDEOGRAPH-F9B2 */
+  {0xf9b3, 1, 4040}, /* CJK COMPATIBILITY IDEOGRAPH-F9B3 */
+  {0xf9b4, 1, 4041}, /* CJK COMPATIBILITY IDEOGRAPH-F9B4 */
+  {0xf9b5, 1, 4042}, /* CJK COMPATIBILITY IDEOGRAPH-F9B5 */
+  {0xf9b6, 1, 4043}, /* CJK COMPATIBILITY IDEOGRAPH-F9B6 */
+  {0xf9b7, 1, 4044}, /* CJK COMPATIBILITY IDEOGRAPH-F9B7 */
+  {0xf9b8, 1, 4045}, /* CJK COMPATIBILITY IDEOGRAPH-F9B8 */
+  {0xf9b9, 1, 4046}, /* CJK COMPATIBILITY IDEOGRAPH-F9B9 */
+  {0xf9ba, 1, 4047}, /* CJK COMPATIBILITY IDEOGRAPH-F9BA */
+  {0xf9bb, 1, 4048}, /* CJK COMPATIBILITY IDEOGRAPH-F9BB */
+  {0xf9bc, 1, 4049}, /* CJK COMPATIBILITY IDEOGRAPH-F9BC */
+  {0xf9bd, 1, 4050}, /* CJK COMPATIBILITY IDEOGRAPH-F9BD */
+  {0xf9be, 1, 4051}, /* CJK COMPATIBILITY IDEOGRAPH-F9BE */
+  {0xf9bf, 1, 3889}, /* CJK COMPATIBILITY IDEOGRAPH-F9BF */
+  {0xf9c0, 1, 4052}, /* CJK COMPATIBILITY IDEOGRAPH-F9C0 */
+  {0xf9c1, 1, 4053}, /* CJK COMPATIBILITY IDEOGRAPH-F9C1 */
+  {0xf9c2, 1, 4054}, /* CJK COMPATIBILITY IDEOGRAPH-F9C2 */
+  {0xf9c3, 1, 4055}, /* CJK COMPATIBILITY IDEOGRAPH-F9C3 */
+  {0xf9c4, 1, 2584}, /* CJK COMPATIBILITY IDEOGRAPH-F9C4 */
+  {0xf9c5, 1, 4056}, /* CJK COMPATIBILITY IDEOGRAPH-F9C5 */
+  {0xf9c6, 1, 4057}, /* CJK COMPATIBILITY IDEOGRAPH-F9C6 */
+  {0xf9c7, 1, 4058}, /* CJK COMPATIBILITY IDEOGRAPH-F9C7 */
+  {0xf9c8, 1, 4059}, /* CJK COMPATIBILITY IDEOGRAPH-F9C8 */
+  {0xf9c9, 1, 4060}, /* CJK COMPATIBILITY IDEOGRAPH-F9C9 */
+  {0xf9ca, 1, 4061}, /* CJK COMPATIBILITY IDEOGRAPH-F9CA */
+  {0xf9cb, 1, 4062}, /* CJK COMPATIBILITY IDEOGRAPH-F9CB */
+  {0xf9cc, 1, 4063}, /* CJK COMPATIBILITY IDEOGRAPH-F9CC */
+  {0xf9cd, 1, 4064}, /* CJK COMPATIBILITY IDEOGRAPH-F9CD */
+  {0xf9ce, 1, 4065}, /* CJK COMPATIBILITY IDEOGRAPH-F9CE */
+  {0xf9cf, 1, 4066}, /* CJK COMPATIBILITY IDEOGRAPH-F9CF */
+  {0xf9d0, 1, 4067}, /* CJK COMPATIBILITY IDEOGRAPH-F9D0 */
+  {0xf9d1, 1, 2950}, /* CJK COMPATIBILITY IDEOGRAPH-F9D1 */
+  {0xf9d2, 1, 4068}, /* CJK COMPATIBILITY IDEOGRAPH-F9D2 */
+  {0xf9d3, 1, 4069}, /* CJK COMPATIBILITY IDEOGRAPH-F9D3 */
+  {0xf9d4, 1, 4070}, /* CJK COMPATIBILITY IDEOGRAPH-F9D4 */
+  {0xf9d5, 1, 4071}, /* CJK COMPATIBILITY IDEOGRAPH-F9D5 */
+  {0xf9d6, 1, 4072}, /* CJK COMPATIBILITY IDEOGRAPH-F9D6 */
+  {0xf9d7, 1, 4073}, /* CJK COMPATIBILITY IDEOGRAPH-F9D7 */
+  {0xf9d8, 1, 4074}, /* CJK COMPATIBILITY IDEOGRAPH-F9D8 */
+  {0xf9d9, 1, 4075}, /* CJK COMPATIBILITY IDEOGRAPH-F9D9 */
+  {0xf9da, 1, 4076}, /* CJK COMPATIBILITY IDEOGRAPH-F9DA */
+  {0xf9db, 1, 3963}, /* CJK COMPATIBILITY IDEOGRAPH-F9DB */
+  {0xf9dc, 1, 4077}, /* CJK COMPATIBILITY IDEOGRAPH-F9DC */
+  {0xf9dd, 1, 4078}, /* CJK COMPATIBILITY IDEOGRAPH-F9DD */
+  {0xf9de, 1, 4079}, /* CJK COMPATIBILITY IDEOGRAPH-F9DE */
+  {0xf9df, 1, 4080}, /* CJK COMPATIBILITY IDEOGRAPH-F9DF */
+  {0xf9e0, 1, 4081}, /* CJK COMPATIBILITY IDEOGRAPH-F9E0 */
+  {0xf9e1, 1, 4082}, /* CJK COMPATIBILITY IDEOGRAPH-F9E1 */
+  {0xf9e2, 1, 4083}, /* CJK COMPATIBILITY IDEOGRAPH-F9E2 */
+  {0xf9e3, 1, 4084}, /* CJK COMPATIBILITY IDEOGRAPH-F9E3 */
+  {0xf9e4, 1, 4085}, /* CJK COMPATIBILITY IDEOGRAPH-F9E4 */
+  {0xf9e5, 1, 4086}, /* CJK COMPATIBILITY IDEOGRAPH-F9E5 */
+  {0xf9e6, 1, 4087}, /* CJK COMPATIBILITY IDEOGRAPH-F9E6 */
+  {0xf9e7, 1, 4088}, /* CJK COMPATIBILITY IDEOGRAPH-F9E7 */
+  {0xf9e8, 1, 4089}, /* CJK COMPATIBILITY IDEOGRAPH-F9E8 */
+  {0xf9e9, 1, 2538}, /* CJK COMPATIBILITY IDEOGRAPH-F9E9 */
+  {0xf9ea, 1, 4090}, /* CJK COMPATIBILITY IDEOGRAPH-F9EA */
+  {0xf9eb, 1, 4091}, /* CJK COMPATIBILITY IDEOGRAPH-F9EB */
+  {0xf9ec, 1, 4092}, /* CJK COMPATIBILITY IDEOGRAPH-F9EC */
+  {0xf9ed, 1, 4093}, /* CJK COMPATIBILITY IDEOGRAPH-F9ED */
+  {0xf9ee, 1, 4094}, /* CJK COMPATIBILITY IDEOGRAPH-F9EE */
+  {0xf9ef, 1, 4095}, /* CJK COMPATIBILITY IDEOGRAPH-F9EF */
+  {0xf9f0, 1, 4096}, /* CJK COMPATIBILITY IDEOGRAPH-F9F0 */
+  {0xf9f1, 1, 4097}, /* CJK COMPATIBILITY IDEOGRAPH-F9F1 */
+  {0xf9f2, 1, 4098}, /* CJK COMPATIBILITY IDEOGRAPH-F9F2 */
+  {0xf9f3, 1, 4099}, /* CJK COMPATIBILITY IDEOGRAPH-F9F3 */
+  {0xf9f4, 1, 4100}, /* CJK COMPATIBILITY IDEOGRAPH-F9F4 */
+  {0xf9f5, 1, 4101}, /* CJK COMPATIBILITY IDEOGRAPH-F9F5 */
+  {0xf9f6, 1, 4102}, /* CJK COMPATIBILITY IDEOGRAPH-F9F6 */
+  {0xf9f7, 1, 2489}, /* CJK COMPATIBILITY IDEOGRAPH-F9F7 */
+  {0xf9f8, 1, 4103}, /* CJK COMPATIBILITY IDEOGRAPH-F9F8 */
+  {0xf9f9, 1, 4104}, /* CJK COMPATIBILITY IDEOGRAPH-F9F9 */
+  {0xf9fa, 1, 4105}, /* CJK COMPATIBILITY IDEOGRAPH-F9FA */
+  {0xf9fb, 1, 4106}, /* CJK COMPATIBILITY IDEOGRAPH-F9FB */
+  {0xf9fc, 1, 4107}, /* CJK COMPATIBILITY IDEOGRAPH-F9FC */
+  {0xf9fd, 1, 4108}, /* CJK COMPATIBILITY IDEOGRAPH-F9FD */
+  {0xf9fe, 1, 4109}, /* CJK COMPATIBILITY IDEOGRAPH-F9FE */
+  {0xf9ff, 1, 4110}, /* CJK COMPATIBILITY IDEOGRAPH-F9FF */
+  {0xfa00, 1, 4111}, /* CJK COMPATIBILITY IDEOGRAPH-FA00 */
+  {0xfa01, 1, 4112}, /* CJK COMPATIBILITY IDEOGRAPH-FA01 */
+  {0xfa02, 1, 4113}, /* CJK COMPATIBILITY IDEOGRAPH-FA02 */
+  {0xfa03, 1, 4114}, /* CJK COMPATIBILITY IDEOGRAPH-FA03 */
+  {0xfa04, 1, 4115}, /* CJK COMPATIBILITY IDEOGRAPH-FA04 */
+  {0xfa05, 1, 4116}, /* CJK COMPATIBILITY IDEOGRAPH-FA05 */
+  {0xfa06, 1, 4117}, /* CJK COMPATIBILITY IDEOGRAPH-FA06 */
+  {0xfa07, 1, 4118}, /* CJK COMPATIBILITY IDEOGRAPH-FA07 */
+  {0xfa08, 1, 2516}, /* CJK COMPATIBILITY IDEOGRAPH-FA08 */
+  {0xfa09, 1, 4119}, /* CJK COMPATIBILITY IDEOGRAPH-FA09 */
+  {0xfa0a, 1, 2519}, /* CJK COMPATIBILITY IDEOGRAPH-FA0A */
+  {0xfa0b, 1, 4120}, /* CJK COMPATIBILITY IDEOGRAPH-FA0B */
+  {0xfa0c, 1, 4121}, /* CJK COMPATIBILITY IDEOGRAPH-FA0C */
+  {0xfa0d, 1, 4122}, /* CJK COMPATIBILITY IDEOGRAPH-FA0D */
+  {0xfa10, 1, 4123}, /* CJK COMPATIBILITY IDEOGRAPH-FA10 */
+  {0xfa12, 1, 4124}, /* CJK COMPATIBILITY IDEOGRAPH-FA12 */
+  {0xfa15, 1, 4125}, /* CJK COMPATIBILITY IDEOGRAPH-FA15 */
+  {0xfa16, 1, 4126}, /* CJK COMPATIBILITY IDEOGRAPH-FA16 */
+  {0xfa17, 1, 4127}, /* CJK COMPATIBILITY IDEOGRAPH-FA17 */
+  {0xfa18, 1, 4128}, /* CJK COMPATIBILITY IDEOGRAPH-FA18 */
+  {0xfa19, 1, 4129}, /* CJK COMPATIBILITY IDEOGRAPH-FA19 */
+  {0xfa1a, 1, 4130}, /* CJK COMPATIBILITY IDEOGRAPH-FA1A */
+  {0xfa1b, 1, 4131}, /* CJK COMPATIBILITY IDEOGRAPH-FA1B */
+  {0xfa1c, 1, 4132}, /* CJK COMPATIBILITY IDEOGRAPH-FA1C */
+  {0xfa1d, 1, 4133}, /* CJK COMPATIBILITY IDEOGRAPH-FA1D */
+  {0xfa1e, 1, 2496}, /* CJK COMPATIBILITY IDEOGRAPH-FA1E */
+  {0xfa20, 1, 4134}, /* CJK COMPATIBILITY IDEOGRAPH-FA20 */
+  {0xfa22, 1, 4135}, /* CJK COMPATIBILITY IDEOGRAPH-FA22 */
+  {0xfa25, 1, 4136}, /* CJK COMPATIBILITY IDEOGRAPH-FA25 */
+  {0xfa26, 1, 4137}, /* CJK COMPATIBILITY IDEOGRAPH-FA26 */
+  {0xfa2a, 1, 4138}, /* CJK COMPATIBILITY IDEOGRAPH-FA2A */
+  {0xfa2b, 1, 4139}, /* CJK COMPATIBILITY IDEOGRAPH-FA2B */
+  {0xfa2c, 1, 4140}, /* CJK COMPATIBILITY IDEOGRAPH-FA2C */
+  {0xfa2d, 1, 4141}, /* CJK COMPATIBILITY IDEOGRAPH-FA2D */
+  {0xfa30, 1, 4142}, /* CJK COMPATIBILITY IDEOGRAPH-FA30 */
+  {0xfa31, 1, 4143}, /* CJK COMPATIBILITY IDEOGRAPH-FA31 */
+  {0xfa32, 1, 4144}, /* CJK COMPATIBILITY IDEOGRAPH-FA32 */
+  {0xfa33, 1, 4145}, /* CJK COMPATIBILITY IDEOGRAPH-FA33 */
+  {0xfa34, 1, 4146}, /* CJK COMPATIBILITY IDEOGRAPH-FA34 */
+  {0xfa35, 1, 4147}, /* CJK COMPATIBILITY IDEOGRAPH-FA35 */
+  {0xfa36, 1, 4148}, /* CJK COMPATIBILITY IDEOGRAPH-FA36 */
+  {0xfa37, 1, 4149}, /* CJK COMPATIBILITY IDEOGRAPH-FA37 */
+  {0xfa38, 1, 4150}, /* CJK COMPATIBILITY IDEOGRAPH-FA38 */
+  {0xfa39, 1, 4151}, /* CJK COMPATIBILITY IDEOGRAPH-FA39 */
+  {0xfa3a, 1, 4152}, /* CJK COMPATIBILITY IDEOGRAPH-FA3A */
+  {0xfa3b, 1, 4153}, /* CJK COMPATIBILITY IDEOGRAPH-FA3B */
+  {0xfa3c, 1, 2417}, /* CJK COMPATIBILITY IDEOGRAPH-FA3C */
+  {0xfa3d, 1, 4154}, /* CJK COMPATIBILITY IDEOGRAPH-FA3D */
+  {0xfa3e, 1, 4155}, /* CJK COMPATIBILITY IDEOGRAPH-FA3E */
+  {0xfa3f, 1, 4156}, /* CJK COMPATIBILITY IDEOGRAPH-FA3F */
+  {0xfa40, 1, 4157}, /* CJK COMPATIBILITY IDEOGRAPH-FA40 */
+  {0xfa41, 1, 4158}, /* CJK COMPATIBILITY IDEOGRAPH-FA41 */
+  {0xfa42, 1, 4159}, /* CJK COMPATIBILITY IDEOGRAPH-FA42 */
+  {0xfa43, 1, 4160}, /* CJK COMPATIBILITY IDEOGRAPH-FA43 */
+  {0xfa44, 1, 4161}, /* CJK COMPATIBILITY IDEOGRAPH-FA44 */
+  {0xfa45, 1, 4162}, /* CJK COMPATIBILITY IDEOGRAPH-FA45 */
+  {0xfa46, 1, 4163}, /* CJK COMPATIBILITY IDEOGRAPH-FA46 */
+  {0xfa47, 1, 4164}, /* CJK COMPATIBILITY IDEOGRAPH-FA47 */
+  {0xfa48, 1, 4165}, /* CJK COMPATIBILITY IDEOGRAPH-FA48 */
+  {0xfa49, 1, 4166}, /* CJK COMPATIBILITY IDEOGRAPH-FA49 */
+  {0xfa4a, 1, 4167}, /* CJK COMPATIBILITY IDEOGRAPH-FA4A */
+  {0xfa4b, 1, 4168}, /* CJK COMPATIBILITY IDEOGRAPH-FA4B */
+  {0xfa4c, 1, 2992}, /* CJK COMPATIBILITY IDEOGRAPH-FA4C */
+  {0xfa4d, 1, 4169}, /* CJK COMPATIBILITY IDEOGRAPH-FA4D */
+  {0xfa4e, 1, 4170}, /* CJK COMPATIBILITY IDEOGRAPH-FA4E */
+  {0xfa4f, 1, 4171}, /* CJK COMPATIBILITY IDEOGRAPH-FA4F */
+  {0xfa50, 1, 4172}, /* CJK COMPATIBILITY IDEOGRAPH-FA50 */
+  {0xfa51, 1, 3004}, /* CJK COMPATIBILITY IDEOGRAPH-FA51 */
+  {0xfa52, 1, 4173}, /* CJK COMPATIBILITY IDEOGRAPH-FA52 */
+  {0xfa53, 1, 4174}, /* CJK COMPATIBILITY IDEOGRAPH-FA53 */
+  {0xfa54, 1, 4175}, /* CJK COMPATIBILITY IDEOGRAPH-FA54 */
+  {0xfa55, 1, 4176}, /* CJK COMPATIBILITY IDEOGRAPH-FA55 */
+  {0xfa56, 1, 4177}, /* CJK COMPATIBILITY IDEOGRAPH-FA56 */
+  {0xfa57, 1, 4013}, /* CJK COMPATIBILITY IDEOGRAPH-FA57 */
+  {0xfa58, 1, 4178}, /* CJK COMPATIBILITY IDEOGRAPH-FA58 */
+  {0xfa59, 1, 4179}, /* CJK COMPATIBILITY IDEOGRAPH-FA59 */
+  {0xfa5a, 1, 4180}, /* CJK COMPATIBILITY IDEOGRAPH-FA5A */
+  {0xfa5b, 1, 4181}, /* CJK COMPATIBILITY IDEOGRAPH-FA5B */
+  {0xfa5c, 1, 4182}, /* CJK COMPATIBILITY IDEOGRAPH-FA5C */
+  {0xfa5d, 1, 4183}, /* CJK COMPATIBILITY IDEOGRAPH-FA5D */
+  {0xfa5e, 1, 4183}, /* CJK COMPATIBILITY IDEOGRAPH-FA5E */
+  {0xfa5f, 1, 4184}, /* CJK COMPATIBILITY IDEOGRAPH-FA5F */
+  {0xfa60, 1, 4185}, /* CJK COMPATIBILITY IDEOGRAPH-FA60 */
+  {0xfa61, 1, 4186}, /* CJK COMPATIBILITY IDEOGRAPH-FA61 */
+  {0xfa62, 1, 4187}, /* CJK COMPATIBILITY IDEOGRAPH-FA62 */
+  {0xfa63, 1, 4188}, /* CJK COMPATIBILITY IDEOGRAPH-FA63 */
+  {0xfa64, 1, 4189}, /* CJK COMPATIBILITY IDEOGRAPH-FA64 */
+  {0xfa65, 1, 4190}, /* CJK COMPATIBILITY IDEOGRAPH-FA65 */
+  {0xfa66, 1, 4191}, /* CJK COMPATIBILITY IDEOGRAPH-FA66 */
+  {0xfa67, 1, 4136}, /* CJK COMPATIBILITY IDEOGRAPH-FA67 */
+  {0xfa68, 1, 4192}, /* CJK COMPATIBILITY IDEOGRAPH-FA68 */
+  {0xfa69, 1, 4193}, /* CJK COMPATIBILITY IDEOGRAPH-FA69 */
+  {0xfa6a, 1, 4194}, /* CJK COMPATIBILITY IDEOGRAPH-FA6A */
+  {0xfb00, 2, 4195}, /* LATIN SMALL LIGATURE FF */
+  {0xfb01, 2, 4197}, /* LATIN SMALL LIGATURE FI */
+  {0xfb02, 2, 4199}, /* LATIN SMALL LIGATURE FL */
+  {0xfb03, 3, 4196}, /* LATIN SMALL LIGATURE FFI */
+  {0xfb04, 3, 4201}, /* LATIN SMALL LIGATURE FFL */
+  {0xfb05, 2, 4204}, /* LATIN SMALL LIGATURE LONG S T */
+  {0xfb06, 2, 4206}, /* LATIN SMALL LIGATURE ST */
+  {0xfb13, 2, 4208}, /* ARMENIAN SMALL LIGATURE MEN NOW */
+  {0xfb14, 2, 4210}, /* ARMENIAN SMALL LIGATURE MEN ECH */
+  {0xfb15, 2, 4212}, /* ARMENIAN SMALL LIGATURE MEN INI */
+  {0xfb16, 2, 4214}, /* ARMENIAN SMALL LIGATURE VEW NOW */
+  {0xfb17, 2, 4216}, /* ARMENIAN SMALL LIGATURE MEN XEH */
+  {0xfb1d, 2, 4218}, /* HEBREW LETTER YOD WITH HIRIQ */
+  {0xfb1f, 2, 4220}, /* HEBREW LIGATURE YIDDISH YOD YOD PATAH */
+  {0xfb20, 1, 4222}, /* HEBREW LETTER ALTERNATIVE AYIN */
+  {0xfb21, 1, 1950}, /* HEBREW LETTER WIDE ALEF */
+  {0xfb22, 1, 1953}, /* HEBREW LETTER WIDE DALET */
+  {0xfb23, 1, 4223}, /* HEBREW LETTER WIDE HE */
+  {0xfb24, 1, 4224}, /* HEBREW LETTER WIDE KAF */
+  {0xfb25, 1, 4225}, /* HEBREW LETTER WIDE LAMED */
+  {0xfb26, 1, 4226}, /* HEBREW LETTER WIDE FINAL MEM */
+  {0xfb27, 1, 4227}, /* HEBREW LETTER WIDE RESH */
+  {0xfb28, 1, 4228}, /* HEBREW LETTER WIDE TAV */
+  {0xfb29, 1, 1915}, /* HEBREW LETTER ALTERNATIVE PLUS SIGN */
+  {0xfb2a, 2, 4229}, /* HEBREW LETTER SHIN WITH SHIN DOT */
+  {0xfb2b, 2, 4231}, /* HEBREW LETTER SHIN WITH SIN DOT */
+  {0xfb2c, 2, 4233}, /* HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT */
+  {0xfb2d, 2, 4235}, /* HEBREW LETTER SHIN WITH DAGESH AND SIN DOT */
+  {0xfb2e, 2, 4237}, /* HEBREW LETTER ALEF WITH PATAH */
+  {0xfb2f, 2, 4239}, /* HEBREW LETTER ALEF WITH QAMATS */
+  {0xfb30, 2, 4241}, /* HEBREW LETTER ALEF WITH MAPIQ */
+  {0xfb31, 2, 4243}, /* HEBREW LETTER BET WITH DAGESH */
+  {0xfb32, 2, 4245}, /* HEBREW LETTER GIMEL WITH DAGESH */
+  {0xfb33, 2, 4247}, /* HEBREW LETTER DALET WITH DAGESH */
+  {0xfb34, 2, 4249}, /* HEBREW LETTER HE WITH MAPIQ */
+  {0xfb35, 2, 4251}, /* HEBREW LETTER VAV WITH DAGESH */
+  {0xfb36, 2, 4253}, /* HEBREW LETTER ZAYIN WITH DAGESH */
+  {0xfb38, 2, 4255}, /* HEBREW LETTER TET WITH DAGESH */
+  {0xfb39, 2, 4257}, /* HEBREW LETTER YOD WITH DAGESH */
+  {0xfb3a, 2, 4259}, /* HEBREW LETTER FINAL KAF WITH DAGESH */
+  {0xfb3b, 2, 4261}, /* HEBREW LETTER KAF WITH DAGESH */
+  {0xfb3c, 2, 4263}, /* HEBREW LETTER LAMED WITH DAGESH */
+  {0xfb3e, 2, 4265}, /* HEBREW LETTER MEM WITH DAGESH */
+  {0xfb40, 2, 4267}, /* HEBREW LETTER NUN WITH DAGESH */
+  {0xfb41, 2, 4269}, /* HEBREW LETTER SAMEKH WITH DAGESH */
+  {0xfb43, 2, 4271}, /* HEBREW LETTER FINAL PE WITH DAGESH */
+  {0xfb44, 2, 4273}, /* HEBREW LETTER PE WITH DAGESH */
+  {0xfb46, 2, 4275}, /* HEBREW LETTER TSADI WITH DAGESH */
+  {0xfb47, 2, 4277}, /* HEBREW LETTER QOF WITH DAGESH */
+  {0xfb48, 2, 4279}, /* HEBREW LETTER RESH WITH DAGESH */
+  {0xfb49, 2, 4281}, /* HEBREW LETTER SHIN WITH DAGESH */
+  {0xfb4a, 2, 4283}, /* HEBREW LETTER TAV WITH DAGESH */
+  {0xfb4b, 2, 4285}, /* HEBREW LETTER VAV WITH HOLAM */
+  {0xfb4c, 2, 4287}, /* HEBREW LETTER BET WITH RAFE */
+  {0xfb4d, 2, 4289}, /* HEBREW LETTER KAF WITH RAFE */
+  {0xfb4e, 2, 4291}, /* HEBREW LETTER PE WITH RAFE */
+  {0xfb4f, 2, 4293}, /* HEBREW LIGATURE ALEF LAMED */
+  {0xfb50, 1, 4295}, /* ARABIC LETTER ALEF WASLA ISOLATED FORM */
+  {0xfb51, 1, 4295}, /* ARABIC LETTER ALEF WASLA FINAL FORM */
+  {0xfb52, 1, 4296}, /* ARABIC LETTER BEEH ISOLATED FORM */
+  {0xfb53, 1, 4296}, /* ARABIC LETTER BEEH FINAL FORM */
+  {0xfb54, 1, 4296}, /* ARABIC LETTER BEEH INITIAL FORM */
+  {0xfb55, 1, 4296}, /* ARABIC LETTER BEEH MEDIAL FORM */
+  {0xfb56, 1, 4297}, /* ARABIC LETTER PEH ISOLATED FORM */
+  {0xfb57, 1, 4297}, /* ARABIC LETTER PEH FINAL FORM */
+  {0xfb58, 1, 4297}, /* ARABIC LETTER PEH INITIAL FORM */
+  {0xfb59, 1, 4297}, /* ARABIC LETTER PEH MEDIAL FORM */
+  {0xfb5a, 1, 4298}, /* ARABIC LETTER BEHEH ISOLATED FORM */
+  {0xfb5b, 1, 4298}, /* ARABIC LETTER BEHEH FINAL FORM */
+  {0xfb5c, 1, 4298}, /* ARABIC LETTER BEHEH INITIAL FORM */
+  {0xfb5d, 1, 4298}, /* ARABIC LETTER BEHEH MEDIAL FORM */
+  {0xfb5e, 1, 4299}, /* ARABIC LETTER TTEHEH ISOLATED FORM */
+  {0xfb5f, 1, 4299}, /* ARABIC LETTER TTEHEH FINAL FORM */
+  {0xfb60, 1, 4299}, /* ARABIC LETTER TTEHEH INITIAL FORM */
+  {0xfb61, 1, 4299}, /* ARABIC LETTER TTEHEH MEDIAL FORM */
+  {0xfb62, 1, 4300}, /* ARABIC LETTER TEHEH ISOLATED FORM */
+  {0xfb63, 1, 4300}, /* ARABIC LETTER TEHEH FINAL FORM */
+  {0xfb64, 1, 4300}, /* ARABIC LETTER TEHEH INITIAL FORM */
+  {0xfb65, 1, 4300}, /* ARABIC LETTER TEHEH MEDIAL FORM */
+  {0xfb66, 1, 4301}, /* ARABIC LETTER TTEH ISOLATED FORM */
+  {0xfb67, 1, 4301}, /* ARABIC LETTER TTEH FINAL FORM */
+  {0xfb68, 1, 4301}, /* ARABIC LETTER TTEH INITIAL FORM */
+  {0xfb69, 1, 4301}, /* ARABIC LETTER TTEH MEDIAL FORM */
+  {0xfb6a, 1, 4302}, /* ARABIC LETTER VEH ISOLATED FORM */
+  {0xfb6b, 1, 4302}, /* ARABIC LETTER VEH FINAL FORM */
+  {0xfb6c, 1, 4302}, /* ARABIC LETTER VEH INITIAL FORM */
+  {0xfb6d, 1, 4302}, /* ARABIC LETTER VEH MEDIAL FORM */
+  {0xfb6e, 1, 4303}, /* ARABIC LETTER PEHEH ISOLATED FORM */
+  {0xfb6f, 1, 4303}, /* ARABIC LETTER PEHEH FINAL FORM */
+  {0xfb70, 1, 4303}, /* ARABIC LETTER PEHEH INITIAL FORM */
+  {0xfb71, 1, 4303}, /* ARABIC LETTER PEHEH MEDIAL FORM */
+  {0xfb72, 1, 4304}, /* ARABIC LETTER DYEH ISOLATED FORM */
+  {0xfb73, 1, 4304}, /* ARABIC LETTER DYEH FINAL FORM */
+  {0xfb74, 1, 4304}, /* ARABIC LETTER DYEH INITIAL FORM */
+  {0xfb75, 1, 4304}, /* ARABIC LETTER DYEH MEDIAL FORM */
+  {0xfb76, 1, 4305}, /* ARABIC LETTER NYEH ISOLATED FORM */
+  {0xfb77, 1, 4305}, /* ARABIC LETTER NYEH FINAL FORM */
+  {0xfb78, 1, 4305}, /* ARABIC LETTER NYEH INITIAL FORM */
+  {0xfb79, 1, 4305}, /* ARABIC LETTER NYEH MEDIAL FORM */
+  {0xfb7a, 1, 4306}, /* ARABIC LETTER TCHEH ISOLATED FORM */
+  {0xfb7b, 1, 4306}, /* ARABIC LETTER TCHEH FINAL FORM */
+  {0xfb7c, 1, 4306}, /* ARABIC LETTER TCHEH INITIAL FORM */
+  {0xfb7d, 1, 4306}, /* ARABIC LETTER TCHEH MEDIAL FORM */
+  {0xfb7e, 1, 4307}, /* ARABIC LETTER TCHEHEH ISOLATED FORM */
+  {0xfb7f, 1, 4307}, /* ARABIC LETTER TCHEHEH FINAL FORM */
+  {0xfb80, 1, 4307}, /* ARABIC LETTER TCHEHEH INITIAL FORM */
+  {0xfb81, 1, 4307}, /* ARABIC LETTER TCHEHEH MEDIAL FORM */
+  {0xfb82, 1, 4308}, /* ARABIC LETTER DDAHAL ISOLATED FORM */
+  {0xfb83, 1, 4308}, /* ARABIC LETTER DDAHAL FINAL FORM */
+  {0xfb84, 1, 4309}, /* ARABIC LETTER DAHAL ISOLATED FORM */
+  {0xfb85, 1, 4309}, /* ARABIC LETTER DAHAL FINAL FORM */
+  {0xfb86, 1, 4310}, /* ARABIC LETTER DUL ISOLATED FORM */
+  {0xfb87, 1, 4310}, /* ARABIC LETTER DUL FINAL FORM */
+  {0xfb88, 1, 4311}, /* ARABIC LETTER DDAL ISOLATED FORM */
+  {0xfb89, 1, 4311}, /* ARABIC LETTER DDAL FINAL FORM */
+  {0xfb8a, 1, 4312}, /* ARABIC LETTER JEH ISOLATED FORM */
+  {0xfb8b, 1, 4312}, /* ARABIC LETTER JEH FINAL FORM */
+  {0xfb8c, 1, 4313}, /* ARABIC LETTER RREH ISOLATED FORM */
+  {0xfb8d, 1, 4313}, /* ARABIC LETTER RREH FINAL FORM */
+  {0xfb8e, 1, 4314}, /* ARABIC LETTER KEHEH ISOLATED FORM */
+  {0xfb8f, 1, 4314}, /* ARABIC LETTER KEHEH FINAL FORM */
+  {0xfb90, 1, 4314}, /* ARABIC LETTER KEHEH INITIAL FORM */
+  {0xfb91, 1, 4314}, /* ARABIC LETTER KEHEH MEDIAL FORM */
+  {0xfb92, 1, 4315}, /* ARABIC LETTER GAF ISOLATED FORM */
+  {0xfb93, 1, 4315}, /* ARABIC LETTER GAF FINAL FORM */
+  {0xfb94, 1, 4315}, /* ARABIC LETTER GAF INITIAL FORM */
+  {0xfb95, 1, 4315}, /* ARABIC LETTER GAF MEDIAL FORM */
+  {0xfb96, 1, 4316}, /* ARABIC LETTER GUEH ISOLATED FORM */
+  {0xfb97, 1, 4316}, /* ARABIC LETTER GUEH FINAL FORM */
+  {0xfb98, 1, 4316}, /* ARABIC LETTER GUEH INITIAL FORM */
+  {0xfb99, 1, 4316}, /* ARABIC LETTER GUEH MEDIAL FORM */
+  {0xfb9a, 1, 4317}, /* ARABIC LETTER NGOEH ISOLATED FORM */
+  {0xfb9b, 1, 4317}, /* ARABIC LETTER NGOEH FINAL FORM */
+  {0xfb9c, 1, 4317}, /* ARABIC LETTER NGOEH INITIAL FORM */
+  {0xfb9d, 1, 4317}, /* ARABIC LETTER NGOEH MEDIAL FORM */
+  {0xfb9e, 1, 4318}, /* ARABIC LETTER NOON GHUNNA ISOLATED FORM */
+  {0xfb9f, 1, 4318}, /* ARABIC LETTER NOON GHUNNA FINAL FORM */
+  {0xfba0, 1, 4319}, /* ARABIC LETTER RNOON ISOLATED FORM */
+  {0xfba1, 1, 4319}, /* ARABIC LETTER RNOON FINAL FORM */
+  {0xfba2, 1, 4319}, /* ARABIC LETTER RNOON INITIAL FORM */
+  {0xfba3, 1, 4319}, /* ARABIC LETTER RNOON MEDIAL FORM */
+  {0xfba4, 1, 4320}, /* ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM */
+  {0xfba5, 1, 4320}, /* ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM */
+  {0xfba6, 1, 769}, /* ARABIC LETTER HEH GOAL ISOLATED FORM */
+  {0xfba7, 1, 769}, /* ARABIC LETTER HEH GOAL FINAL FORM */
+  {0xfba8, 1, 769}, /* ARABIC LETTER HEH GOAL INITIAL FORM */
+  {0xfba9, 1, 769}, /* ARABIC LETTER HEH GOAL MEDIAL FORM */
+  {0xfbaa, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM */
+  {0xfbab, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE FINAL FORM */
+  {0xfbac, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE INITIAL FORM */
+  {0xfbad, 1, 4321}, /* ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM */
+  {0xfbae, 1, 771}, /* ARABIC LETTER YEH BARREE ISOLATED FORM */
+  {0xfbaf, 1, 771}, /* ARABIC LETTER YEH BARREE FINAL FORM */
+  {0xfbb0, 1, 4322}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfbb1, 1, 4322}, /* ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM */
+  {0xfbd3, 1, 4323}, /* ARABIC LETTER NG ISOLATED FORM */
+  {0xfbd4, 1, 4323}, /* ARABIC LETTER NG FINAL FORM */
+  {0xfbd5, 1, 4323}, /* ARABIC LETTER NG INITIAL FORM */
+  {0xfbd6, 1, 4323}, /* ARABIC LETTER NG MEDIAL FORM */
+  {0xfbd7, 1, 763}, /* ARABIC LETTER U ISOLATED FORM */
+  {0xfbd8, 1, 763}, /* ARABIC LETTER U FINAL FORM */
+  {0xfbd9, 1, 4324}, /* ARABIC LETTER OE ISOLATED FORM */
+  {0xfbda, 1, 4324}, /* ARABIC LETTER OE FINAL FORM */
+  {0xfbdb, 1, 4325}, /* ARABIC LETTER YU ISOLATED FORM */
+  {0xfbdc, 1, 4325}, /* ARABIC LETTER YU FINAL FORM */
+  {0xfbdd, 1, 4326}, /* ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfbde, 1, 4327}, /* ARABIC LETTER VE ISOLATED FORM */
+  {0xfbdf, 1, 4327}, /* ARABIC LETTER VE FINAL FORM */
+  {0xfbe0, 1, 4328}, /* ARABIC LETTER KIRGHIZ OE ISOLATED FORM */
+  {0xfbe1, 1, 4328}, /* ARABIC LETTER KIRGHIZ OE FINAL FORM */
+  {0xfbe2, 1, 4329}, /* ARABIC LETTER KIRGHIZ YU ISOLATED FORM */
+  {0xfbe3, 1, 4329}, /* ARABIC LETTER KIRGHIZ YU FINAL FORM */
+  {0xfbe4, 1, 4330}, /* ARABIC LETTER E ISOLATED FORM */
+  {0xfbe5, 1, 4330}, /* ARABIC LETTER E FINAL FORM */
+  {0xfbe6, 1, 4330}, /* ARABIC LETTER E INITIAL FORM */
+  {0xfbe7, 1, 4330}, /* ARABIC LETTER E MEDIAL FORM */
+  {0xfbe8, 1, 4331}, /* ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM */
+  {0xfbe9, 1, 4331}, /* ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM */
+  {0xfbea, 2, 4332}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM */
+  {0xfbeb, 2, 4332}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM */
+  {0xfbec, 2, 4334}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM */
+  {0xfbed, 2, 4334}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM */
+  {0xfbee, 2, 4336}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM */
+  {0xfbef, 2, 4336}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM */
+  {0xfbf0, 2, 4338}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM */
+  {0xfbf1, 2, 4338}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM */
+  {0xfbf2, 2, 4340}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM */
+  {0xfbf3, 2, 4340}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM */
+  {0xfbf4, 2, 4342}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM */
+  {0xfbf5, 2, 4342}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM */
+  {0xfbf6, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM */
+  {0xfbf7, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM */
+  {0xfbf8, 2, 4344}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM */
+  {0xfbf9, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfbfa, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM */
+  {0xfbfb, 2, 4346}, /* ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM */
+  {0xfbfc, 1, 4348}, /* ARABIC LETTER FARSI YEH ISOLATED FORM */
+  {0xfbfd, 1, 4348}, /* ARABIC LETTER FARSI YEH FINAL FORM */
+  {0xfbfe, 1, 4348}, /* ARABIC LETTER FARSI YEH INITIAL FORM */
+  {0xfbff, 1, 4348}, /* ARABIC LETTER FARSI YEH MEDIAL FORM */
+  {0xfc00, 2, 4349}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM */
+  {0xfc01, 2, 4351}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM */
+  {0xfc02, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM */
+  {0xfc03, 2, 4346}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc04, 2, 4355}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM */
+  {0xfc05, 2, 4357}, /* ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM */
+  {0xfc06, 2, 4359}, /* ARABIC LIGATURE BEH WITH HAH ISOLATED FORM */
+  {0xfc07, 2, 4361}, /* ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM */
+  {0xfc08, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM */
+  {0xfc09, 2, 4365}, /* ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc0a, 2, 4367}, /* ARABIC LIGATURE BEH WITH YEH ISOLATED FORM */
+  {0xfc0b, 2, 4369}, /* ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM */
+  {0xfc0c, 2, 4371}, /* ARABIC LIGATURE TEH WITH HAH ISOLATED FORM */
+  {0xfc0d, 2, 4373}, /* ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM */
+  {0xfc0e, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM */
+  {0xfc0f, 2, 4377}, /* ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc10, 2, 4379}, /* ARABIC LIGATURE TEH WITH YEH ISOLATED FORM */
+  {0xfc11, 2, 4381}, /* ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM */
+  {0xfc12, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM */
+  {0xfc13, 2, 4385}, /* ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc14, 2, 4387}, /* ARABIC LIGATURE THEH WITH YEH ISOLATED FORM */
+  {0xfc15, 2, 4389}, /* ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM */
+  {0xfc16, 2, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM */
+  {0xfc17, 2, 4390}, /* ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM */
+  {0xfc18, 2, 4393}, /* ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM */
+  {0xfc19, 2, 4395}, /* ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM */
+  {0xfc1a, 2, 4397}, /* ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM */
+  {0xfc1b, 2, 4399}, /* ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM */
+  {0xfc1c, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM */
+  {0xfc1d, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM */
+  {0xfc1e, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM */
+  {0xfc1f, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM */
+  {0xfc20, 2, 4409}, /* ARABIC LIGATURE SAD WITH HAH ISOLATED FORM */
+  {0xfc21, 2, 4411}, /* ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM */
+  {0xfc22, 2, 4413}, /* ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM */
+  {0xfc23, 2, 4415}, /* ARABIC LIGATURE DAD WITH HAH ISOLATED FORM */
+  {0xfc24, 2, 4417}, /* ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM */
+  {0xfc25, 2, 4419}, /* ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM */
+  {0xfc26, 2, 4421}, /* ARABIC LIGATURE TAH WITH HAH ISOLATED FORM */
+  {0xfc27, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM */
+  {0xfc28, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM */
+  {0xfc29, 2, 4427}, /* ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM */
+  {0xfc2a, 2, 4429}, /* ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM */
+  {0xfc2b, 2, 4431}, /* ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM */
+  {0xfc2c, 2, 4433}, /* ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM */
+  {0xfc2d, 2, 4435}, /* ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM */
+  {0xfc2e, 2, 4437}, /* ARABIC LIGATURE FEH WITH HAH ISOLATED FORM */
+  {0xfc2f, 2, 4439}, /* ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM */
+  {0xfc30, 2, 4441}, /* ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM */
+  {0xfc31, 2, 4443}, /* ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc32, 2, 4445}, /* ARABIC LIGATURE FEH WITH YEH ISOLATED FORM */
+  {0xfc33, 2, 4447}, /* ARABIC LIGATURE QAF WITH HAH ISOLATED FORM */
+  {0xfc34, 2, 4449}, /* ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM */
+  {0xfc35, 2, 4451}, /* ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc36, 2, 4453}, /* ARABIC LIGATURE QAF WITH YEH ISOLATED FORM */
+  {0xfc37, 2, 4455}, /* ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM */
+  {0xfc38, 2, 4457}, /* ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM */
+  {0xfc39, 2, 4459}, /* ARABIC LIGATURE KAF WITH HAH ISOLATED FORM */
+  {0xfc3a, 2, 4461}, /* ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM */
+  {0xfc3b, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM ISOLATED FORM */
+  {0xfc3c, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM */
+  {0xfc3d, 2, 4467}, /* ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc3e, 2, 4469}, /* ARABIC LIGATURE KAF WITH YEH ISOLATED FORM */
+  {0xfc3f, 2, 4471}, /* ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM */
+  {0xfc40, 2, 4473}, /* ARABIC LIGATURE LAM WITH HAH ISOLATED FORM */
+  {0xfc41, 2, 4475}, /* ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM */
+  {0xfc42, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM */
+  {0xfc43, 2, 4479}, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc44, 2, 4481}, /* ARABIC LIGATURE LAM WITH YEH ISOLATED FORM */
+  {0xfc45, 2, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM */
+  {0xfc46, 2, 4392}, /* ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM */
+  {0xfc47, 2, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM */
+  {0xfc48, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM */
+  {0xfc49, 2, 4487}, /* ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc4a, 2, 4489}, /* ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM */
+  {0xfc4b, 2, 4491}, /* ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM */
+  {0xfc4c, 2, 4493}, /* ARABIC LIGATURE NOON WITH HAH ISOLATED FORM */
+  {0xfc4d, 2, 4495}, /* ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM */
+  {0xfc4e, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM */
+  {0xfc4f, 2, 4499}, /* ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc50, 2, 4501}, /* ARABIC LIGATURE NOON WITH YEH ISOLATED FORM */
+  {0xfc51, 2, 4503}, /* ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM */
+  {0xfc52, 2, 4505}, /* ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM */
+  {0xfc53, 2, 4507}, /* ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc54, 2, 4509}, /* ARABIC LIGATURE HEH WITH YEH ISOLATED FORM */
+  {0xfc55, 2, 4388}, /* ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM */
+  {0xfc56, 2, 4511}, /* ARABIC LIGATURE YEH WITH HAH ISOLATED FORM */
+  {0xfc57, 2, 4513}, /* ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM */
+  {0xfc58, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM */
+  {0xfc59, 2, 4515}, /* ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfc5a, 2, 4510}, /* ARABIC LIGATURE YEH WITH YEH ISOLATED FORM */
+  {0xfc5b, 2, 4517}, /* ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM */
+  {0xfc5c, 2, 4519}, /* ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM */
+  {0xfc5d, 2, 4521}, /* ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM */
+  {0xfc5e, 3, 4523}, /* ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM */
+  {0xfc5f, 3, 4526}, /* ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM */
+  {0xfc60, 3, 4529}, /* ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM */
+  {0xfc61, 3, 4532}, /* ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM */
+  {0xfc62, 3, 4535}, /* ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM */
+  {0xfc63, 3, 4538}, /* ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM */
+  {0xfc64, 2, 4541}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM */
+  {0xfc65, 2, 4543}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM */
+  {0xfc66, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM */
+  {0xfc67, 2, 4545}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM */
+  {0xfc68, 2, 4346}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM */
+  {0xfc69, 2, 4355}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM */
+  {0xfc6a, 2, 4547}, /* ARABIC LIGATURE BEH WITH REH FINAL FORM */
+  {0xfc6b, 2, 4549}, /* ARABIC LIGATURE BEH WITH ZAIN FINAL FORM */
+  {0xfc6c, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM FINAL FORM */
+  {0xfc6d, 2, 4551}, /* ARABIC LIGATURE BEH WITH NOON FINAL FORM */
+  {0xfc6e, 2, 4365}, /* ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM */
+  {0xfc6f, 2, 4367}, /* ARABIC LIGATURE BEH WITH YEH FINAL FORM */
+  {0xfc70, 2, 4553}, /* ARABIC LIGATURE TEH WITH REH FINAL FORM */
+  {0xfc71, 2, 4555}, /* ARABIC LIGATURE TEH WITH ZAIN FINAL FORM */
+  {0xfc72, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM FINAL FORM */
+  {0xfc73, 2, 4557}, /* ARABIC LIGATURE TEH WITH NOON FINAL FORM */
+  {0xfc74, 2, 4377}, /* ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM */
+  {0xfc75, 2, 4379}, /* ARABIC LIGATURE TEH WITH YEH FINAL FORM */
+  {0xfc76, 2, 4559}, /* ARABIC LIGATURE THEH WITH REH FINAL FORM */
+  {0xfc77, 2, 4561}, /* ARABIC LIGATURE THEH WITH ZAIN FINAL FORM */
+  {0xfc78, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM FINAL FORM */
+  {0xfc79, 2, 4563}, /* ARABIC LIGATURE THEH WITH NOON FINAL FORM */
+  {0xfc7a, 2, 4385}, /* ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM */
+  {0xfc7b, 2, 4387}, /* ARABIC LIGATURE THEH WITH YEH FINAL FORM */
+  {0xfc7c, 2, 4443}, /* ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM */
+  {0xfc7d, 2, 4445}, /* ARABIC LIGATURE FEH WITH YEH FINAL FORM */
+  {0xfc7e, 2, 4451}, /* ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM */
+  {0xfc7f, 2, 4453}, /* ARABIC LIGATURE QAF WITH YEH FINAL FORM */
+  {0xfc80, 2, 4455}, /* ARABIC LIGATURE KAF WITH ALEF FINAL FORM */
+  {0xfc81, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM FINAL FORM */
+  {0xfc82, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM FINAL FORM */
+  {0xfc83, 2, 4467}, /* ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM */
+  {0xfc84, 2, 4469}, /* ARABIC LIGATURE KAF WITH YEH FINAL FORM */
+  {0xfc85, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM FINAL FORM */
+  {0xfc86, 2, 4479}, /* ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM */
+  {0xfc87, 2, 4481}, /* ARABIC LIGATURE LAM WITH YEH FINAL FORM */
+  {0xfc88, 2, 4565}, /* ARABIC LIGATURE MEEM WITH ALEF FINAL FORM */
+  {0xfc89, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM FINAL FORM */
+  {0xfc8a, 2, 4567}, /* ARABIC LIGATURE NOON WITH REH FINAL FORM */
+  {0xfc8b, 2, 4569}, /* ARABIC LIGATURE NOON WITH ZAIN FINAL FORM */
+  {0xfc8c, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM FINAL FORM */
+  {0xfc8d, 2, 4571}, /* ARABIC LIGATURE NOON WITH NOON FINAL FORM */
+  {0xfc8e, 2, 4499}, /* ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM */
+  {0xfc8f, 2, 4501}, /* ARABIC LIGATURE NOON WITH YEH FINAL FORM */
+  {0xfc90, 2, 4521}, /* ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM */
+  {0xfc91, 2, 4573}, /* ARABIC LIGATURE YEH WITH REH FINAL FORM */
+  {0xfc92, 2, 4575}, /* ARABIC LIGATURE YEH WITH ZAIN FINAL FORM */
+  {0xfc93, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM FINAL FORM */
+  {0xfc94, 2, 4490}, /* ARABIC LIGATURE YEH WITH NOON FINAL FORM */
+  {0xfc95, 2, 4515}, /* ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM */
+  {0xfc96, 2, 4510}, /* ARABIC LIGATURE YEH WITH YEH FINAL FORM */
+  {0xfc97, 2, 4349}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM */
+  {0xfc98, 2, 4351}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM */
+  {0xfc99, 2, 4577}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM */
+  {0xfc9a, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM */
+  {0xfc9b, 2, 4579}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM */
+  {0xfc9c, 2, 4357}, /* ARABIC LIGATURE BEH WITH JEEM INITIAL FORM */
+  {0xfc9d, 2, 4359}, /* ARABIC LIGATURE BEH WITH HAH INITIAL FORM */
+  {0xfc9e, 2, 4361}, /* ARABIC LIGATURE BEH WITH KHAH INITIAL FORM */
+  {0xfc9f, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM INITIAL FORM */
+  {0xfca0, 2, 4581}, /* ARABIC LIGATURE BEH WITH HEH INITIAL FORM */
+  {0xfca1, 2, 4369}, /* ARABIC LIGATURE TEH WITH JEEM INITIAL FORM */
+  {0xfca2, 2, 4371}, /* ARABIC LIGATURE TEH WITH HAH INITIAL FORM */
+  {0xfca3, 2, 4373}, /* ARABIC LIGATURE TEH WITH KHAH INITIAL FORM */
+  {0xfca4, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM INITIAL FORM */
+  {0xfca5, 2, 4583}, /* ARABIC LIGATURE TEH WITH HEH INITIAL FORM */
+  {0xfca6, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM INITIAL FORM */
+  {0xfca7, 2, 4389}, /* ARABIC LIGATURE JEEM WITH HAH INITIAL FORM */
+  {0xfca8, 2, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM */
+  {0xfca9, 2, 4390}, /* ARABIC LIGATURE HAH WITH JEEM INITIAL FORM */
+  {0xfcaa, 2, 4393}, /* ARABIC LIGATURE HAH WITH MEEM INITIAL FORM */
+  {0xfcab, 2, 4395}, /* ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM */
+  {0xfcac, 2, 4399}, /* ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM */
+  {0xfcad, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM */
+  {0xfcae, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH INITIAL FORM */
+  {0xfcaf, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM */
+  {0xfcb0, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM */
+  {0xfcb1, 2, 4409}, /* ARABIC LIGATURE SAD WITH HAH INITIAL FORM */
+  {0xfcb2, 2, 4585}, /* ARABIC LIGATURE SAD WITH KHAH INITIAL FORM */
+  {0xfcb3, 2, 4411}, /* ARABIC LIGATURE SAD WITH MEEM INITIAL FORM */
+  {0xfcb4, 2, 4413}, /* ARABIC LIGATURE DAD WITH JEEM INITIAL FORM */
+  {0xfcb5, 2, 4415}, /* ARABIC LIGATURE DAD WITH HAH INITIAL FORM */
+  {0xfcb6, 2, 4417}, /* ARABIC LIGATURE DAD WITH KHAH INITIAL FORM */
+  {0xfcb7, 2, 4419}, /* ARABIC LIGATURE DAD WITH MEEM INITIAL FORM */
+  {0xfcb8, 2, 4421}, /* ARABIC LIGATURE TAH WITH HAH INITIAL FORM */
+  {0xfcb9, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM */
+  {0xfcba, 2, 4427}, /* ARABIC LIGATURE AIN WITH JEEM INITIAL FORM */
+  {0xfcbb, 2, 4429}, /* ARABIC LIGATURE AIN WITH MEEM INITIAL FORM */
+  {0xfcbc, 2, 4431}, /* ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM */
+  {0xfcbd, 2, 4433}, /* ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM */
+  {0xfcbe, 2, 4435}, /* ARABIC LIGATURE FEH WITH JEEM INITIAL FORM */
+  {0xfcbf, 2, 4437}, /* ARABIC LIGATURE FEH WITH HAH INITIAL FORM */
+  {0xfcc0, 2, 4439}, /* ARABIC LIGATURE FEH WITH KHAH INITIAL FORM */
+  {0xfcc1, 2, 4441}, /* ARABIC LIGATURE FEH WITH MEEM INITIAL FORM */
+  {0xfcc2, 2, 4447}, /* ARABIC LIGATURE QAF WITH HAH INITIAL FORM */
+  {0xfcc3, 2, 4449}, /* ARABIC LIGATURE QAF WITH MEEM INITIAL FORM */
+  {0xfcc4, 2, 4457}, /* ARABIC LIGATURE KAF WITH JEEM INITIAL FORM */
+  {0xfcc5, 2, 4459}, /* ARABIC LIGATURE KAF WITH HAH INITIAL FORM */
+  {0xfcc6, 2, 4461}, /* ARABIC LIGATURE KAF WITH KHAH INITIAL FORM */
+  {0xfcc7, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM INITIAL FORM */
+  {0xfcc8, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM INITIAL FORM */
+  {0xfcc9, 2, 4471}, /* ARABIC LIGATURE LAM WITH JEEM INITIAL FORM */
+  {0xfcca, 2, 4473}, /* ARABIC LIGATURE LAM WITH HAH INITIAL FORM */
+  {0xfccb, 2, 4475}, /* ARABIC LIGATURE LAM WITH KHAH INITIAL FORM */
+  {0xfccc, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM INITIAL FORM */
+  {0xfccd, 2, 4587}, /* ARABIC LIGATURE LAM WITH HEH INITIAL FORM */
+  {0xfcce, 2, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM */
+  {0xfccf, 2, 4392}, /* ARABIC LIGATURE MEEM WITH HAH INITIAL FORM */
+  {0xfcd0, 2, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM */
+  {0xfcd1, 2, 4485}, /* ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM */
+  {0xfcd2, 2, 4491}, /* ARABIC LIGATURE NOON WITH JEEM INITIAL FORM */
+  {0xfcd3, 2, 4493}, /* ARABIC LIGATURE NOON WITH HAH INITIAL FORM */
+  {0xfcd4, 2, 4495}, /* ARABIC LIGATURE NOON WITH KHAH INITIAL FORM */
+  {0xfcd5, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM INITIAL FORM */
+  {0xfcd6, 2, 4589}, /* ARABIC LIGATURE NOON WITH HEH INITIAL FORM */
+  {0xfcd7, 2, 4503}, /* ARABIC LIGATURE HEH WITH JEEM INITIAL FORM */
+  {0xfcd8, 2, 4505}, /* ARABIC LIGATURE HEH WITH MEEM INITIAL FORM */
+  {0xfcd9, 2, 4591}, /* ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM */
+  {0xfcda, 2, 4388}, /* ARABIC LIGATURE YEH WITH JEEM INITIAL FORM */
+  {0xfcdb, 2, 4511}, /* ARABIC LIGATURE YEH WITH HAH INITIAL FORM */
+  {0xfcdc, 2, 4513}, /* ARABIC LIGATURE YEH WITH KHAH INITIAL FORM */
+  {0xfcdd, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM INITIAL FORM */
+  {0xfcde, 2, 4502}, /* ARABIC LIGATURE YEH WITH HEH INITIAL FORM */
+  {0xfcdf, 2, 4353}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM */
+  {0xfce0, 2, 4579}, /* ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM */
+  {0xfce1, 2, 4363}, /* ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM */
+  {0xfce2, 2, 4581}, /* ARABIC LIGATURE BEH WITH HEH MEDIAL FORM */
+  {0xfce3, 2, 4375}, /* ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM */
+  {0xfce4, 2, 4583}, /* ARABIC LIGATURE TEH WITH HEH MEDIAL FORM */
+  {0xfce5, 2, 4383}, /* ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM */
+  {0xfce6, 2, 4593}, /* ARABIC LIGATURE THEH WITH HEH MEDIAL FORM */
+  {0xfce7, 2, 4407}, /* ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM */
+  {0xfce8, 2, 4595}, /* ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM */
+  {0xfce9, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM */
+  {0xfcea, 2, 4599}, /* ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM */
+  {0xfceb, 2, 4463}, /* ARABIC LIGATURE KAF WITH LAM MEDIAL FORM */
+  {0xfcec, 2, 4465}, /* ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM */
+  {0xfced, 2, 4477}, /* ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM */
+  {0xfcee, 2, 4497}, /* ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM */
+  {0xfcef, 2, 4589}, /* ARABIC LIGATURE NOON WITH HEH MEDIAL FORM */
+  {0xfcf0, 2, 4482}, /* ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM */
+  {0xfcf1, 2, 4502}, /* ARABIC LIGATURE YEH WITH HEH MEDIAL FORM */
+  {0xfcf2, 3, 4601}, /* ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM */
+  {0xfcf3, 3, 4604}, /* ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM */
+  {0xfcf4, 3, 4607}, /* ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM */
+  {0xfcf5, 2, 4610}, /* ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfcf6, 2, 4612}, /* ARABIC LIGATURE TAH WITH YEH ISOLATED FORM */
+  {0xfcf7, 2, 4614}, /* ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfcf8, 2, 4616}, /* ARABIC LIGATURE AIN WITH YEH ISOLATED FORM */
+  {0xfcf9, 2, 4618}, /* ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfcfa, 2, 4620}, /* ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM */
+  {0xfcfb, 2, 4622}, /* ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfcfc, 2, 4624}, /* ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM */
+  {0xfcfd, 2, 4626}, /* ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfcfe, 2, 4628}, /* ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM */
+  {0xfcff, 2, 4630}, /* ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfd00, 2, 4512}, /* ARABIC LIGATURE HAH WITH YEH ISOLATED FORM */
+  {0xfd01, 2, 4632}, /* ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfd02, 2, 4634}, /* ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM */
+  {0xfd03, 2, 4636}, /* ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfd04, 2, 4514}, /* ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM */
+  {0xfd05, 2, 4638}, /* ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfd06, 2, 4640}, /* ARABIC LIGATURE SAD WITH YEH ISOLATED FORM */
+  {0xfd07, 2, 4642}, /* ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM */
+  {0xfd08, 2, 4644}, /* ARABIC LIGATURE DAD WITH YEH ISOLATED FORM */
+  {0xfd09, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM */
+  {0xfd0a, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM */
+  {0xfd0b, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM */
+  {0xfd0c, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM */
+  {0xfd0d, 2, 4652}, /* ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM */
+  {0xfd0e, 2, 4654}, /* ARABIC LIGATURE SEEN WITH REH ISOLATED FORM */
+  {0xfd0f, 2, 4656}, /* ARABIC LIGATURE SAD WITH REH ISOLATED FORM */
+  {0xfd10, 2, 4658}, /* ARABIC LIGATURE DAD WITH REH ISOLATED FORM */
+  {0xfd11, 2, 4610}, /* ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd12, 2, 4612}, /* ARABIC LIGATURE TAH WITH YEH FINAL FORM */
+  {0xfd13, 2, 4614}, /* ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM */
+  {0xfd14, 2, 4616}, /* ARABIC LIGATURE AIN WITH YEH FINAL FORM */
+  {0xfd15, 2, 4618}, /* ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM */
+  {0xfd16, 2, 4620}, /* ARABIC LIGATURE GHAIN WITH YEH FINAL FORM */
+  {0xfd17, 2, 4622}, /* ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM */
+  {0xfd18, 2, 4624}, /* ARABIC LIGATURE SEEN WITH YEH FINAL FORM */
+  {0xfd19, 2, 4626}, /* ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM */
+  {0xfd1a, 2, 4628}, /* ARABIC LIGATURE SHEEN WITH YEH FINAL FORM */
+  {0xfd1b, 2, 4630}, /* ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd1c, 2, 4512}, /* ARABIC LIGATURE HAH WITH YEH FINAL FORM */
+  {0xfd1d, 2, 4632}, /* ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd1e, 2, 4634}, /* ARABIC LIGATURE JEEM WITH YEH FINAL FORM */
+  {0xfd1f, 2, 4636}, /* ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd20, 2, 4514}, /* ARABIC LIGATURE KHAH WITH YEH FINAL FORM */
+  {0xfd21, 2, 4638}, /* ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM */
+  {0xfd22, 2, 4640}, /* ARABIC LIGATURE SAD WITH YEH FINAL FORM */
+  {0xfd23, 2, 4642}, /* ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM */
+  {0xfd24, 2, 4644}, /* ARABIC LIGATURE DAD WITH YEH FINAL FORM */
+  {0xfd25, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM */
+  {0xfd26, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH FINAL FORM */
+  {0xfd27, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM */
+  {0xfd28, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM */
+  {0xfd29, 2, 4652}, /* ARABIC LIGATURE SHEEN WITH REH FINAL FORM */
+  {0xfd2a, 2, 4654}, /* ARABIC LIGATURE SEEN WITH REH FINAL FORM */
+  {0xfd2b, 2, 4656}, /* ARABIC LIGATURE SAD WITH REH FINAL FORM */
+  {0xfd2c, 2, 4658}, /* ARABIC LIGATURE DAD WITH REH FINAL FORM */
+  {0xfd2d, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM */
+  {0xfd2e, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM */
+  {0xfd2f, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM */
+  {0xfd30, 2, 4597}, /* ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM */
+  {0xfd31, 2, 4595}, /* ARABIC LIGATURE SEEN WITH HEH INITIAL FORM */
+  {0xfd32, 2, 4599}, /* ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM */
+  {0xfd33, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM INITIAL FORM */
+  {0xfd34, 2, 4401}, /* ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM */
+  {0xfd35, 2, 4403}, /* ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM */
+  {0xfd36, 2, 4405}, /* ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM */
+  {0xfd37, 2, 4646}, /* ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM */
+  {0xfd38, 2, 4648}, /* ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM */
+  {0xfd39, 2, 4650}, /* ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM */
+  {0xfd3a, 2, 4423}, /* ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM */
+  {0xfd3b, 2, 4425}, /* ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM */
+  {0xfd3c, 2, 4660}, /* ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM */
+  {0xfd3d, 2, 4660}, /* ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM */
+  {0xfd50, 3, 4662}, /* ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM */
+  {0xfd51, 3, 4665}, /* ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM */
+  {0xfd52, 3, 4665}, /* ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM */
+  {0xfd53, 3, 4668}, /* ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM */
+  {0xfd54, 3, 4671}, /* ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM */
+  {0xfd55, 3, 4674}, /* ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM */
+  {0xfd56, 3, 4677}, /* ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM */
+  {0xfd57, 3, 4680}, /* ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM */
+  {0xfd58, 3, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM */
+  {0xfd59, 3, 4391}, /* ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM */
+  {0xfd5a, 3, 4683}, /* ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM */
+  {0xfd5b, 3, 4686}, /* ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd5c, 3, 4689}, /* ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM */
+  {0xfd5d, 3, 4692}, /* ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM */
+  {0xfd5e, 3, 4695}, /* ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd5f, 3, 4698}, /* ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM */
+  {0xfd60, 3, 4698}, /* ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM */
+  {0xfd61, 3, 4701}, /* ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM */
+  {0xfd62, 3, 4704}, /* ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd63, 3, 4704}, /* ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd64, 3, 4707}, /* ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM */
+  {0xfd65, 3, 4707}, /* ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM */
+  {0xfd66, 3, 4710}, /* ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd67, 3, 4713}, /* ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM */
+  {0xfd68, 3, 4713}, /* ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM */
+  {0xfd69, 3, 4716}, /* ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM */
+  {0xfd6a, 3, 4719}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM */
+  {0xfd6b, 3, 4719}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM */
+  {0xfd6c, 3, 4722}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd6d, 3, 4722}, /* ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd6e, 3, 4725}, /* ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd6f, 3, 4728}, /* ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM */
+  {0xfd70, 3, 4728}, /* ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM */
+  {0xfd71, 3, 4731}, /* ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM */
+  {0xfd72, 3, 4731}, /* ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM */
+  {0xfd73, 3, 4734}, /* ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd74, 3, 4737}, /* ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM */
+  {0xfd75, 3, 4740}, /* ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM */
+  {0xfd76, 3, 4743}, /* ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd77, 3, 4743}, /* ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd78, 3, 4746}, /* ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd79, 3, 4749}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd7a, 3, 4752}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM */
+  {0xfd7b, 3, 4755}, /* ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd7c, 3, 4758}, /* ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM */
+  {0xfd7d, 3, 4758}, /* ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM */
+  {0xfd7e, 3, 4761}, /* ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM */
+  {0xfd7f, 3, 4764}, /* ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd80, 3, 4767}, /* ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM */
+  {0xfd81, 3, 4770}, /* ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM */
+  {0xfd82, 3, 4773}, /* ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd83, 3, 4776}, /* ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM */
+  {0xfd84, 3, 4776}, /* ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM */
+  {0xfd85, 3, 4779}, /* ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM */
+  {0xfd86, 3, 4779}, /* ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM */
+  {0xfd87, 3, 4782}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM */
+  {0xfd88, 3, 4782}, /* ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM */
+  {0xfd89, 3, 4785}, /* ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM */
+  {0xfd8a, 3, 4392}, /* ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM */
+  {0xfd8b, 3, 4788}, /* ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM */
+  {0xfd8c, 3, 4791}, /* ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM */
+  {0xfd8d, 3, 4483}, /* ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM */
+  {0xfd8e, 3, 4394}, /* ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM */
+  {0xfd8f, 3, 4794}, /* ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM */
+  {0xfd92, 3, 4797}, /* ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM */
+  {0xfd93, 3, 4800}, /* ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM */
+  {0xfd94, 3, 4803}, /* ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd95, 3, 4806}, /* ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM */
+  {0xfd96, 3, 4809}, /* ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfd97, 3, 4812}, /* ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM */
+  {0xfd98, 3, 4812}, /* ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM */
+  {0xfd99, 3, 4815}, /* ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd9a, 3, 4818}, /* ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM */
+  {0xfd9b, 3, 4821}, /* ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfd9c, 3, 4824}, /* ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM */
+  {0xfd9d, 3, 4824}, /* ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfd9e, 3, 4827}, /* ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM */
+  {0xfd9f, 3, 4830}, /* ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM */
+  {0xfda0, 3, 4833}, /* ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfda1, 3, 4836}, /* ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM */
+  {0xfda2, 3, 4839}, /* ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfda3, 3, 4842}, /* ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM */
+  {0xfda4, 3, 4845}, /* ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfda5, 3, 4848}, /* ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM */
+  {0xfda6, 3, 4851}, /* ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfda7, 3, 4854}, /* ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM */
+  {0xfda8, 3, 4857}, /* ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM */
+  {0xfda9, 3, 4860}, /* ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM */
+  {0xfdaa, 3, 4863}, /* ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM */
+  {0xfdab, 3, 4866}, /* ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM */
+  {0xfdac, 3, 4869}, /* ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM */
+  {0xfdad, 3, 4872}, /* ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM */
+  {0xfdae, 3, 4511}, /* ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM */
+  {0xfdaf, 3, 4875}, /* ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM */
+  {0xfdb0, 3, 4878}, /* ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM */
+  {0xfdb1, 3, 4881}, /* ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM */
+  {0xfdb2, 3, 4884}, /* ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM */
+  {0xfdb3, 3, 4887}, /* ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM */
+  {0xfdb4, 3, 4761}, /* ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM */
+  {0xfdb5, 3, 4767}, /* ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM */
+  {0xfdb6, 3, 4890}, /* ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM */
+  {0xfdb7, 3, 4893}, /* ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM */
+  {0xfdb8, 3, 4896}, /* ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM */
+  {0xfdb9, 3, 4899}, /* ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM */
+  {0xfdba, 3, 4902}, /* ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM */
+  {0xfdbb, 3, 4905}, /* ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM */
+  {0xfdbc, 3, 4902}, /* ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM */
+  {0xfdbd, 3, 4896}, /* ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM */
+  {0xfdbe, 3, 4908}, /* ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM */
+  {0xfdbf, 3, 4911}, /* ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM */
+  {0xfdc0, 3, 4914}, /* ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM */
+  {0xfdc1, 3, 4917}, /* ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM */
+  {0xfdc2, 3, 4920}, /* ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM */
+  {0xfdc3, 3, 4905}, /* ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfdc4, 3, 4740}, /* ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM */
+  {0xfdc5, 3, 4710}, /* ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM */
+  {0xfdc6, 3, 4923}, /* ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM */
+  {0xfdc7, 3, 4926}, /* ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM */
+  {0xfdf0, 3, 4929}, /* ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM */
+  {0xfdf1, 3, 4932}, /* ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM */
+  {0xfdf2, 4, 4935}, /* ARABIC LIGATURE ALLAH ISOLATED FORM */
+  {0xfdf3, 4, 4939}, /* ARABIC LIGATURE AKBAR ISOLATED FORM */
+  {0xfdf4, 4, 4943}, /* ARABIC LIGATURE MOHAMMAD ISOLATED FORM */
+  {0xfdf5, 4, 4947}, /* ARABIC LIGATURE SALAM ISOLATED FORM */
+  {0xfdf6, 4, 4951}, /* ARABIC LIGATURE RASOUL ISOLATED FORM */
+  {0xfdf7, 4, 4955}, /* ARABIC LIGATURE ALAYHE ISOLATED FORM */
+  {0xfdf8, 4, 4959}, /* ARABIC LIGATURE WASALLAM ISOLATED FORM */
+  {0xfdf9, 3, 4963}, /* ARABIC LIGATURE SALLA ISOLATED FORM */
+  {0xfdfa, 18, 4966}, /* ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM */
+  {0xfdfb, 8, 4984}, /* ARABIC LIGATURE JALLAJALALOUHOU */
+  {0xfdfc, 4, 4992}, /* RIAL SIGN */
+  {0xfe30, 1, 4996}, /* PRESENTATION FORM FOR VERTICAL TWO DOT LEADER */
+  {0xfe31, 1, 4997}, /* PRESENTATION FORM FOR VERTICAL EM DASH */
+  {0xfe32, 1, 4998}, /* PRESENTATION FORM FOR VERTICAL EN DASH */
+  {0xfe33, 1, 4999}, /* PRESENTATION FORM FOR VERTICAL LOW LINE */
+  {0xfe34, 1, 4999}, /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE */
+  {0xfe35, 1, 1918}, /* PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS */
+  {0xfe36, 1, 1919}, /* PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS */
+  {0xfe37, 1, 5000}, /* PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET */
+  {0xfe38, 1, 5001}, /* PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET */
+  {0xfe39, 1, 5002}, /* PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET */
+  {0xfe3a, 1, 5003}, /* PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET */
+  {0xfe3b, 1, 5004}, /* PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET */
+  {0xfe3c, 1, 5005}, /* PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET */
+  {0xfe3d, 1, 5006}, /* PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET */
+  {0xfe3e, 1, 5007}, /* PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET */
+  {0xfe3f, 1, 2140}, /* PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET */
+  {0xfe40, 1, 2141}, /* PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET */
+  {0xfe41, 1, 5008}, /* PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET */
+  {0xfe42, 1, 5009}, /* PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET */
+  {0xfe43, 1, 5010}, /* PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET */
+  {0xfe44, 1, 5011}, /* PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET */
+  {0xfe47, 1, 5012}, /* PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET */
+  {0xfe48, 1, 5013}, /* PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET */
+  {0xfe49, 1, 5014}, /* DASHED OVERLINE */
+  {0xfe4a, 1, 5014}, /* CENTRELINE OVERLINE */
+  {0xfe4b, 1, 5014}, /* WAVY OVERLINE */
+  {0xfe4c, 1, 5014}, /* DOUBLE WAVY OVERLINE */
+  {0xfe4d, 1, 4999}, /* DASHED LOW LINE */
+  {0xfe4e, 1, 4999}, /* CENTRELINE LOW LINE */
+  {0xfe4f, 1, 4999}, /* WAVY LOW LINE */
+  {0xfe50, 1, 5015}, /* SMALL COMMA */
+  {0xfe51, 1, 5016}, /* SMALL IDEOGRAPHIC COMMA */
+  {0xfe52, 1, 1884}, /* SMALL FULL STOP */
+  {0xfe54, 1, 587}, /* SMALL SEMICOLON */
+  {0xfe55, 1, 2364}, /* SMALL COLON */
+  {0xfe56, 1, 1902}, /* SMALL QUESTION MARK */
+  {0xfe57, 1, 1898}, /* SMALL EXCLAMATION MARK */
+  {0xfe58, 1, 4997}, /* SMALL EM DASH */
+  {0xfe59, 1, 1918}, /* SMALL LEFT PARENTHESIS */
+  {0xfe5a, 1, 1919}, /* SMALL RIGHT PARENTHESIS */
+  {0xfe5b, 1, 5000}, /* SMALL LEFT CURLY BRACKET */
+  {0xfe5c, 1, 5001}, /* SMALL RIGHT CURLY BRACKET */
+  {0xfe5d, 1, 5002}, /* SMALL LEFT TORTOISE SHELL BRACKET */
+  {0xfe5e, 1, 5003}, /* SMALL RIGHT TORTOISE SHELL BRACKET */
+  {0xfe5f, 1, 5017}, /* SMALL NUMBER SIGN */
+  {0xfe60, 1, 5018}, /* SMALL AMPERSAND */
+  {0xfe61, 1, 5019}, /* SMALL ASTERISK */
+  {0xfe62, 1, 1915}, /* SMALL PLUS SIGN */
+  {0xfe63, 1, 5020}, /* SMALL HYPHEN-MINUS */
+  {0xfe64, 1, 2088}, /* SMALL LESS-THAN SIGN */
+  {0xfe65, 1, 2090}, /* SMALL GREATER-THAN SIGN */
+  {0xfe66, 1, 1917}, /* SMALL EQUALS SIGN */
+  {0xfe68, 1, 5021}, /* SMALL REVERSE SOLIDUS */
+  {0xfe69, 1, 5022}, /* SMALL DOLLAR SIGN */
+  {0xfe6a, 1, 5023}, /* SMALL PERCENT SIGN */
+  {0xfe6b, 1, 5024}, /* SMALL COMMERCIAL AT */
+  {0xfe70, 2, 5025}, /* ARABIC FATHATAN ISOLATED FORM */
+  {0xfe71, 2, 5027}, /* ARABIC TATWEEL WITH FATHATAN ABOVE */
+  {0xfe72, 2, 4523}, /* ARABIC DAMMATAN ISOLATED FORM */
+  {0xfe74, 2, 4526}, /* ARABIC KASRATAN ISOLATED FORM */
+  {0xfe76, 2, 4529}, /* ARABIC FATHA ISOLATED FORM */
+  {0xfe77, 2, 4601}, /* ARABIC FATHA MEDIAL FORM */
+  {0xfe78, 2, 4532}, /* ARABIC DAMMA ISOLATED FORM */
+  {0xfe79, 2, 4604}, /* ARABIC DAMMA MEDIAL FORM */
+  {0xfe7a, 2, 4535}, /* ARABIC KASRA ISOLATED FORM */
+  {0xfe7b, 2, 4607}, /* ARABIC KASRA MEDIAL FORM */
+  {0xfe7c, 2, 4538}, /* ARABIC SHADDA ISOLATED FORM */
+  {0xfe7d, 2, 5029}, /* ARABIC SHADDA MEDIAL FORM */
+  {0xfe7e, 2, 5031}, /* ARABIC SUKUN ISOLATED FORM */
+  {0xfe7f, 2, 5033}, /* ARABIC SUKUN MEDIAL FORM */
+  {0xfe80, 1, 5035}, /* ARABIC LETTER HAMZA ISOLATED FORM */
+  {0xfe81, 1, 5036}, /* ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM */
+  {0xfe82, 1, 5036}, /* ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM */
+  {0xfe83, 1, 5037}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfe84, 1, 5037}, /* ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM */
+  {0xfe85, 1, 5038}, /* ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfe86, 1, 5038}, /* ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM */
+  {0xfe87, 1, 5039}, /* ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM */
+  {0xfe88, 1, 5039}, /* ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM */
+  {0xfe89, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfe8a, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM */
+  {0xfe8b, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM */
+  {0xfe8c, 1, 4332}, /* ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM */
+  {0xfe8d, 1, 749}, /* ARABIC LETTER ALEF ISOLATED FORM */
+  {0xfe8e, 1, 749}, /* ARABIC LETTER ALEF FINAL FORM */
+  {0xfe8f, 1, 4357}, /* ARABIC LETTER BEH ISOLATED FORM */
+  {0xfe90, 1, 4357}, /* ARABIC LETTER BEH FINAL FORM */
+  {0xfe91, 1, 4357}, /* ARABIC LETTER BEH INITIAL FORM */
+  {0xfe92, 1, 4357}, /* ARABIC LETTER BEH MEDIAL FORM */
+  {0xfe93, 1, 5040}, /* ARABIC LETTER TEH MARBUTA ISOLATED FORM */
+  {0xfe94, 1, 5040}, /* ARABIC LETTER TEH MARBUTA FINAL FORM */
+  {0xfe95, 1, 4369}, /* ARABIC LETTER TEH ISOLATED FORM */
+  {0xfe96, 1, 4369}, /* ARABIC LETTER TEH FINAL FORM */
+  {0xfe97, 1, 4369}, /* ARABIC LETTER TEH INITIAL FORM */
+  {0xfe98, 1, 4369}, /* ARABIC LETTER TEH MEDIAL FORM */
+  {0xfe99, 1, 4381}, /* ARABIC LETTER THEH ISOLATED FORM */
+  {0xfe9a, 1, 4381}, /* ARABIC LETTER THEH FINAL FORM */
+  {0xfe9b, 1, 4381}, /* ARABIC LETTER THEH INITIAL FORM */
+  {0xfe9c, 1, 4381}, /* ARABIC LETTER THEH MEDIAL FORM */
+  {0xfe9d, 1, 4350}, /* ARABIC LETTER JEEM ISOLATED FORM */
+  {0xfe9e, 1, 4350}, /* ARABIC LETTER JEEM FINAL FORM */
+  {0xfe9f, 1, 4350}, /* ARABIC LETTER JEEM INITIAL FORM */
+  {0xfea0, 1, 4350}, /* ARABIC LETTER JEEM MEDIAL FORM */
+  {0xfea1, 1, 4352}, /* ARABIC LETTER HAH ISOLATED FORM */
+  {0xfea2, 1, 4352}, /* ARABIC LETTER HAH FINAL FORM */
+  {0xfea3, 1, 4352}, /* ARABIC LETTER HAH INITIAL FORM */
+  {0xfea4, 1, 4352}, /* ARABIC LETTER HAH MEDIAL FORM */
+  {0xfea5, 1, 4362}, /* ARABIC LETTER KHAH ISOLATED FORM */
+  {0xfea6, 1, 4362}, /* ARABIC LETTER KHAH FINAL FORM */
+  {0xfea7, 1, 4362}, /* ARABIC LETTER KHAH INITIAL FORM */
+  {0xfea8, 1, 4362}, /* ARABIC LETTER KHAH MEDIAL FORM */
+  {0xfea9, 1, 4946}, /* ARABIC LETTER DAL ISOLATED FORM */
+  {0xfeaa, 1, 4946}, /* ARABIC LETTER DAL FINAL FORM */
+  {0xfeab, 1, 4517}, /* ARABIC LETTER THAL ISOLATED FORM */
+  {0xfeac, 1, 4517}, /* ARABIC LETTER THAL FINAL FORM */
+  {0xfead, 1, 4519}, /* ARABIC LETTER REH ISOLATED FORM */
+  {0xfeae, 1, 4519}, /* ARABIC LETTER REH FINAL FORM */
+  {0xfeaf, 1, 4544}, /* ARABIC LETTER ZAIN ISOLATED FORM */
+  {0xfeb0, 1, 4544}, /* ARABIC LETTER ZAIN FINAL FORM */
+  {0xfeb1, 1, 4401}, /* ARABIC LETTER SEEN ISOLATED FORM */
+  {0xfeb2, 1, 4401}, /* ARABIC LETTER SEEN FINAL FORM */
+  {0xfeb3, 1, 4401}, /* ARABIC LETTER SEEN INITIAL FORM */
+  {0xfeb4, 1, 4401}, /* ARABIC LETTER SEEN MEDIAL FORM */
+  {0xfeb5, 1, 4597}, /* ARABIC LETTER SHEEN ISOLATED FORM */
+  {0xfeb6, 1, 4597}, /* ARABIC LETTER SHEEN FINAL FORM */
+  {0xfeb7, 1, 4597}, /* ARABIC LETTER SHEEN INITIAL FORM */
+  {0xfeb8, 1, 4597}, /* ARABIC LETTER SHEEN MEDIAL FORM */
+  {0xfeb9, 1, 4409}, /* ARABIC LETTER SAD ISOLATED FORM */
+  {0xfeba, 1, 4409}, /* ARABIC LETTER SAD FINAL FORM */
+  {0xfebb, 1, 4409}, /* ARABIC LETTER SAD INITIAL FORM */
+  {0xfebc, 1, 4409}, /* ARABIC LETTER SAD MEDIAL FORM */
+  {0xfebd, 1, 4413}, /* ARABIC LETTER DAD ISOLATED FORM */
+  {0xfebe, 1, 4413}, /* ARABIC LETTER DAD FINAL FORM */
+  {0xfebf, 1, 4413}, /* ARABIC LETTER DAD INITIAL FORM */
+  {0xfec0, 1, 4413}, /* ARABIC LETTER DAD MEDIAL FORM */
+  {0xfec1, 1, 4421}, /* ARABIC LETTER TAH ISOLATED FORM */
+  {0xfec2, 1, 4421}, /* ARABIC LETTER TAH FINAL FORM */
+  {0xfec3, 1, 4421}, /* ARABIC LETTER TAH INITIAL FORM */
+  {0xfec4, 1, 4421}, /* ARABIC LETTER TAH MEDIAL FORM */
+  {0xfec5, 1, 4425}, /* ARABIC LETTER ZAH ISOLATED FORM */
+  {0xfec6, 1, 4425}, /* ARABIC LETTER ZAH FINAL FORM */
+  {0xfec7, 1, 4425}, /* ARABIC LETTER ZAH INITIAL FORM */
+  {0xfec8, 1, 4425}, /* ARABIC LETTER ZAH MEDIAL FORM */
+  {0xfec9, 1, 4427}, /* ARABIC LETTER AIN ISOLATED FORM */
+  {0xfeca, 1, 4427}, /* ARABIC LETTER AIN FINAL FORM */
+  {0xfecb, 1, 4427}, /* ARABIC LETTER AIN INITIAL FORM */
+  {0xfecc, 1, 4427}, /* ARABIC LETTER AIN MEDIAL FORM */
+  {0xfecd, 1, 4431}, /* ARABIC LETTER GHAIN ISOLATED FORM */
+  {0xfece, 1, 4431}, /* ARABIC LETTER GHAIN FINAL FORM */
+  {0xfecf, 1, 4431}, /* ARABIC LETTER GHAIN INITIAL FORM */
+  {0xfed0, 1, 4431}, /* ARABIC LETTER GHAIN MEDIAL FORM */
+  {0xfed1, 1, 4435}, /* ARABIC LETTER FEH ISOLATED FORM */
+  {0xfed2, 1, 4435}, /* ARABIC LETTER FEH FINAL FORM */
+  {0xfed3, 1, 4435}, /* ARABIC LETTER FEH INITIAL FORM */
+  {0xfed4, 1, 4435}, /* ARABIC LETTER FEH MEDIAL FORM */
+  {0xfed5, 1, 4447}, /* ARABIC LETTER QAF ISOLATED FORM */
+  {0xfed6, 1, 4447}, /* ARABIC LETTER QAF FINAL FORM */
+  {0xfed7, 1, 4447}, /* ARABIC LETTER QAF INITIAL FORM */
+  {0xfed8, 1, 4447}, /* ARABIC LETTER QAF MEDIAL FORM */
+  {0xfed9, 1, 4455}, /* ARABIC LETTER KAF ISOLATED FORM */
+  {0xfeda, 1, 4455}, /* ARABIC LETTER KAF FINAL FORM */
+  {0xfedb, 1, 4455}, /* ARABIC LETTER KAF INITIAL FORM */
+  {0xfedc, 1, 4455}, /* ARABIC LETTER KAF MEDIAL FORM */
+  {0xfedd, 1, 4464}, /* ARABIC LETTER LAM ISOLATED FORM */
+  {0xfede, 1, 4464}, /* ARABIC LETTER LAM FINAL FORM */
+  {0xfedf, 1, 4464}, /* ARABIC LETTER LAM INITIAL FORM */
+  {0xfee0, 1, 4464}, /* ARABIC LETTER LAM MEDIAL FORM */
+  {0xfee1, 1, 4354}, /* ARABIC LETTER MEEM ISOLATED FORM */
+  {0xfee2, 1, 4354}, /* ARABIC LETTER MEEM FINAL FORM */
+  {0xfee3, 1, 4354}, /* ARABIC LETTER MEEM INITIAL FORM */
+  {0xfee4, 1, 4354}, /* ARABIC LETTER MEEM MEDIAL FORM */
+  {0xfee5, 1, 4491}, /* ARABIC LETTER NOON ISOLATED FORM */
+  {0xfee6, 1, 4491}, /* ARABIC LETTER NOON FINAL FORM */
+  {0xfee7, 1, 4491}, /* ARABIC LETTER NOON INITIAL FORM */
+  {0xfee8, 1, 4491}, /* ARABIC LETTER NOON MEDIAL FORM */
+  {0xfee9, 1, 4503}, /* ARABIC LETTER HEH ISOLATED FORM */
+  {0xfeea, 1, 4503}, /* ARABIC LETTER HEH FINAL FORM */
+  {0xfeeb, 1, 4503}, /* ARABIC LETTER HEH INITIAL FORM */
+  {0xfeec, 1, 4503}, /* ARABIC LETTER HEH MEDIAL FORM */
+  {0xfeed, 1, 753}, /* ARABIC LETTER WAW ISOLATED FORM */
+  {0xfeee, 1, 753}, /* ARABIC LETTER WAW FINAL FORM */
+  {0xfeef, 1, 4331}, /* ARABIC LETTER ALEF MAKSURA ISOLATED FORM */
+  {0xfef0, 1, 4331}, /* ARABIC LETTER ALEF MAKSURA FINAL FORM */
+  {0xfef1, 1, 757}, /* ARABIC LETTER YEH ISOLATED FORM */
+  {0xfef2, 1, 757}, /* ARABIC LETTER YEH FINAL FORM */
+  {0xfef3, 1, 757}, /* ARABIC LETTER YEH INITIAL FORM */
+  {0xfef4, 1, 757}, /* ARABIC LETTER YEH MEDIAL FORM */
+  {0xfef5, 2, 5041}, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
+  {0xfef6, 2, 5041}, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
+  {0xfef7, 2, 5043}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
+  {0xfef8, 2, 5043}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
+  {0xfef9, 2, 5045}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
+  {0xfefa, 2, 5045}, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
+  {0xfefb, 2, 4988}, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
+  {0xfefc, 2, 4988}, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
+  {0xff01, 1, 1898}, /* FULLWIDTH EXCLAMATION MARK */
+  {0xff02, 1, 5047}, /* FULLWIDTH QUOTATION MARK */
+  {0xff03, 1, 5017}, /* FULLWIDTH NUMBER SIGN */
+  {0xff04, 1, 5022}, /* FULLWIDTH DOLLAR SIGN */
+  {0xff05, 1, 5023}, /* FULLWIDTH PERCENT SIGN */
+  {0xff06, 1, 5018}, /* FULLWIDTH AMPERSAND */
+  {0xff07, 1, 5048}, /* FULLWIDTH APOSTROPHE */
+  {0xff08, 1, 1918}, /* FULLWIDTH LEFT PARENTHESIS */
+  {0xff09, 1, 1919}, /* FULLWIDTH RIGHT PARENTHESIS */
+  {0xff0a, 1, 5019}, /* FULLWIDTH ASTERISK */
+  {0xff0b, 1, 1915}, /* FULLWIDTH PLUS SIGN */
+  {0xff0c, 1, 5015}, /* FULLWIDTH COMMA */
+  {0xff0d, 1, 5020}, /* FULLWIDTH HYPHEN-MINUS */
+  {0xff0e, 1, 1884}, /* FULLWIDTH FULL STOP */
+  {0xff0f, 1, 1923}, /* FULLWIDTH SOLIDUS */
+  {0xff10, 1, 1909}, /* FULLWIDTH DIGIT ZERO */
+  {0xff11, 1, 13}, /* FULLWIDTH DIGIT ONE */
+  {0xff12, 1, 6}, /* FULLWIDTH DIGIT TWO */
+  {0xff13, 1, 7}, /* FULLWIDTH DIGIT THREE */
+  {0xff14, 1, 17}, /* FULLWIDTH DIGIT FOUR */
+  {0xff15, 1, 1910}, /* FULLWIDTH DIGIT FIVE */
+  {0xff16, 1, 1911}, /* FULLWIDTH DIGIT SIX */
+  {0xff17, 1, 1912}, /* FULLWIDTH DIGIT SEVEN */
+  {0xff18, 1, 1913}, /* FULLWIDTH DIGIT EIGHT */
+  {0xff19, 1, 1914}, /* FULLWIDTH DIGIT NINE */
+  {0xff1a, 1, 2364}, /* FULLWIDTH COLON */
+  {0xff1b, 1, 587}, /* FULLWIDTH SEMICOLON */
+  {0xff1c, 1, 2088}, /* FULLWIDTH LESS-THAN SIGN */
+  {0xff1d, 1, 1917}, /* FULLWIDTH EQUALS SIGN */
+  {0xff1e, 1, 2090}, /* FULLWIDTH GREATER-THAN SIGN */
+  {0xff1f, 1, 1902}, /* FULLWIDTH QUESTION MARK */
+  {0xff20, 1, 5024}, /* FULLWIDTH COMMERCIAL AT */
+  {0xff21, 1, 24}, /* FULLWIDTH LATIN CAPITAL LETTER A */
+  {0xff22, 1, 910}, /* FULLWIDTH LATIN CAPITAL LETTER B */
+  {0xff23, 1, 36}, /* FULLWIDTH LATIN CAPITAL LETTER C */
+  {0xff24, 1, 158}, /* FULLWIDTH LATIN CAPITAL LETTER D */
+  {0xff25, 1, 38}, /* FULLWIDTH LATIN CAPITAL LETTER E */
+  {0xff26, 1, 995}, /* FULLWIDTH LATIN CAPITAL LETTER F */
+  {0xff27, 1, 182}, /* FULLWIDTH LATIN CAPITAL LETTER G */
+  {0xff28, 1, 198}, /* FULLWIDTH LATIN CAPITAL LETTER H */
+  {0xff29, 1, 46}, /* FULLWIDTH LATIN CAPITAL LETTER I */
+  {0xff2a, 1, 221}, /* FULLWIDTH LATIN CAPITAL LETTER J */
+  {0xff2b, 1, 228}, /* FULLWIDTH LATIN CAPITAL LETTER K */
+  {0xff2c, 1, 232}, /* FULLWIDTH LATIN CAPITAL LETTER L */
+  {0xff2d, 1, 912}, /* FULLWIDTH LATIN CAPITAL LETTER M */
+  {0xff2e, 1, 54}, /* FULLWIDTH LATIN CAPITAL LETTER N */
+  {0xff2f, 1, 56}, /* FULLWIDTH LATIN CAPITAL LETTER O */
+  {0xff30, 1, 914}, /* FULLWIDTH LATIN CAPITAL LETTER P */
+  {0xff31, 1, 1942}, /* FULLWIDTH LATIN CAPITAL LETTER Q */
+  {0xff32, 1, 274}, /* FULLWIDTH LATIN CAPITAL LETTER R */
+  {0xff33, 1, 286}, /* FULLWIDTH LATIN CAPITAL LETTER S */
+  {0xff34, 1, 302}, /* FULLWIDTH LATIN CAPITAL LETTER T */
+  {0xff35, 1, 66}, /* FULLWIDTH LATIN CAPITAL LETTER U */
+  {0xff36, 1, 1183}, /* FULLWIDTH LATIN CAPITAL LETTER V */
+  {0xff37, 1, 334}, /* FULLWIDTH LATIN CAPITAL LETTER W */
+  {0xff38, 1, 1211}, /* FULLWIDTH LATIN CAPITAL LETTER X */
+  {0xff39, 1, 74}, /* FULLWIDTH LATIN CAPITAL LETTER Y */
+  {0xff3a, 1, 344}, /* FULLWIDTH LATIN CAPITAL LETTER Z */
+  {0xff3b, 1, 5012}, /* FULLWIDTH LEFT SQUARE BRACKET */
+  {0xff3c, 1, 5021}, /* FULLWIDTH REVERSE SOLIDUS */
+  {0xff3d, 1, 5013}, /* FULLWIDTH RIGHT SQUARE BRACKET */
+  {0xff3e, 1, 5049}, /* FULLWIDTH CIRCUMFLEX ACCENT */
+  {0xff3f, 1, 4999}, /* FULLWIDTH LOW LINE */
+  {0xff40, 1, 1848}, /* FULLWIDTH GRAVE ACCENT */
+  {0xff41, 1, 3}, /* FULLWIDTH LATIN SMALL LETTER A */
+  {0xff42, 1, 918}, /* FULLWIDTH LATIN SMALL LETTER B */
+  {0xff43, 1, 88}, /* FULLWIDTH LATIN SMALL LETTER C */
+  {0xff44, 1, 160}, /* FULLWIDTH LATIN SMALL LETTER D */
+  {0xff45, 1, 90}, /* FULLWIDTH LATIN SMALL LETTER E */
+  {0xff46, 1, 997}, /* FULLWIDTH LATIN SMALL LETTER F */
+  {0xff47, 1, 184}, /* FULLWIDTH LATIN SMALL LETTER G */
+  {0xff48, 1, 200}, /* FULLWIDTH LATIN SMALL LETTER H */
+  {0xff49, 1, 98}, /* FULLWIDTH LATIN SMALL LETTER I */
+  {0xff4a, 1, 223}, /* FULLWIDTH LATIN SMALL LETTER J */
+  {0xff4b, 1, 230}, /* FULLWIDTH LATIN SMALL LETTER K */
+  {0xff4c, 1, 234}, /* FULLWIDTH LATIN SMALL LETTER L */
+  {0xff4d, 1, 922}, /* FULLWIDTH LATIN SMALL LETTER M */
+  {0xff4e, 1, 106}, /* FULLWIDTH LATIN SMALL LETTER N */
+  {0xff4f, 1, 14}, /* FULLWIDTH LATIN SMALL LETTER O */
+  {0xff50, 1, 927}, /* FULLWIDTH LATIN SMALL LETTER P */
+  {0xff51, 1, 2335}, /* FULLWIDTH LATIN SMALL LETTER Q */
+  {0xff52, 1, 276}, /* FULLWIDTH LATIN SMALL LETTER R */
+  {0xff53, 1, 288}, /* FULLWIDTH LATIN SMALL LETTER S */
+  {0xff54, 1, 304}, /* FULLWIDTH LATIN SMALL LETTER T */
+  {0xff55, 1, 118}, /* FULLWIDTH LATIN SMALL LETTER U */
+  {0xff56, 1, 930}, /* FULLWIDTH LATIN SMALL LETTER V */
+  {0xff57, 1, 336}, /* FULLWIDTH LATIN SMALL LETTER W */
+  {0xff58, 1, 579}, /* FULLWIDTH LATIN SMALL LETTER X */
+  {0xff59, 1, 126}, /* FULLWIDTH LATIN SMALL LETTER Y */
+  {0xff5a, 1, 346}, /* FULLWIDTH LATIN SMALL LETTER Z */
+  {0xff5b, 1, 5000}, /* FULLWIDTH LEFT CURLY BRACKET */
+  {0xff5c, 1, 5050}, /* FULLWIDTH VERTICAL LINE */
+  {0xff5d, 1, 5001}, /* FULLWIDTH RIGHT CURLY BRACKET */
+  {0xff5e, 1, 5051}, /* FULLWIDTH TILDE */
+  {0xff5f, 1, 5052}, /* FULLWIDTH LEFT WHITE PARENTHESIS */
+  {0xff60, 1, 5053}, /* FULLWIDTH RIGHT WHITE PARENTHESIS */
+  {0xff61, 1, 5054}, /* HALFWIDTH IDEOGRAPHIC FULL STOP */
+  {0xff62, 1, 5008}, /* HALFWIDTH LEFT CORNER BRACKET */
+  {0xff63, 1, 5009}, /* HALFWIDTH RIGHT CORNER BRACKET */
+  {0xff64, 1, 5016}, /* HALFWIDTH IDEOGRAPHIC COMMA */
+  {0xff65, 1, 5055}, /* HALFWIDTH KATAKANA MIDDLE DOT */
+  {0xff66, 1, 2709}, /* HALFWIDTH KATAKANA LETTER WO */
+  {0xff67, 1, 3180}, /* HALFWIDTH KATAKANA LETTER SMALL A */
+  {0xff68, 1, 3348}, /* HALFWIDTH KATAKANA LETTER SMALL I */
+  {0xff69, 1, 5056}, /* HALFWIDTH KATAKANA LETTER SMALL U */
+  {0xff6a, 1, 3354}, /* HALFWIDTH KATAKANA LETTER SMALL E */
+  {0xff6b, 1, 3196}, /* HALFWIDTH KATAKANA LETTER SMALL O */
+  {0xff6c, 1, 5057}, /* HALFWIDTH KATAKANA LETTER SMALL YA */
+  {0xff6d, 1, 3236}, /* HALFWIDTH KATAKANA LETTER SMALL YU */
+  {0xff6e, 1, 3415}, /* HALFWIDTH KATAKANA LETTER SMALL YO */
+  {0xff6f, 1, 3218}, /* HALFWIDTH KATAKANA LETTER SMALL TU */
+  {0xff70, 1, 3175}, /* HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+  {0xff71, 1, 3151}, /* HALFWIDTH KATAKANA LETTER A */
+  {0xff72, 1, 3152}, /* HALFWIDTH KATAKANA LETTER I */
+  {0xff73, 1, 2701}, /* HALFWIDTH KATAKANA LETTER U */
+  {0xff74, 1, 3153}, /* HALFWIDTH KATAKANA LETTER E */
+  {0xff75, 1, 3154}, /* HALFWIDTH KATAKANA LETTER O */
+  {0xff76, 1, 2651}, /* HALFWIDTH KATAKANA LETTER KA */
+  {0xff77, 1, 2653}, /* HALFWIDTH KATAKANA LETTER KI */
+  {0xff78, 1, 2655}, /* HALFWIDTH KATAKANA LETTER KU */
+  {0xff79, 1, 2657}, /* HALFWIDTH KATAKANA LETTER KE */
+  {0xff7a, 1, 2659}, /* HALFWIDTH KATAKANA LETTER KO */
+  {0xff7b, 1, 2661}, /* HALFWIDTH KATAKANA LETTER SA */
+  {0xff7c, 1, 2663}, /* HALFWIDTH KATAKANA LETTER SI */
+  {0xff7d, 1, 2665}, /* HALFWIDTH KATAKANA LETTER SU */
+  {0xff7e, 1, 2667}, /* HALFWIDTH KATAKANA LETTER SE */
+  {0xff7f, 1, 2669}, /* HALFWIDTH KATAKANA LETTER SO */
+  {0xff80, 1, 2671}, /* HALFWIDTH KATAKANA LETTER TA */
+  {0xff81, 1, 2673}, /* HALFWIDTH KATAKANA LETTER TI */
+  {0xff82, 1, 2675}, /* HALFWIDTH KATAKANA LETTER TU */
+  {0xff83, 1, 2677}, /* HALFWIDTH KATAKANA LETTER TE */
+  {0xff84, 1, 2679}, /* HALFWIDTH KATAKANA LETTER TO */
+  {0xff85, 1, 3155}, /* HALFWIDTH KATAKANA LETTER NA */
+  {0xff86, 1, 3156}, /* HALFWIDTH KATAKANA LETTER NI */
+  {0xff87, 1, 3157}, /* HALFWIDTH KATAKANA LETTER NU */
+  {0xff88, 1, 3158}, /* HALFWIDTH KATAKANA LETTER NE */
+  {0xff89, 1, 3159}, /* HALFWIDTH KATAKANA LETTER NO */
+  {0xff8a, 1, 2681}, /* HALFWIDTH KATAKANA LETTER HA */
+  {0xff8b, 1, 2685}, /* HALFWIDTH KATAKANA LETTER HI */
+  {0xff8c, 1, 2689}, /* HALFWIDTH KATAKANA LETTER HU */
+  {0xff8d, 1, 2693}, /* HALFWIDTH KATAKANA LETTER HE */
+  {0xff8e, 1, 2697}, /* HALFWIDTH KATAKANA LETTER HO */
+  {0xff8f, 1, 3160}, /* HALFWIDTH KATAKANA LETTER MA */
+  {0xff90, 1, 3161}, /* HALFWIDTH KATAKANA LETTER MI */
+  {0xff91, 1, 3162}, /* HALFWIDTH KATAKANA LETTER MU */
+  {0xff92, 1, 3163}, /* HALFWIDTH KATAKANA LETTER ME */
+  {0xff93, 1, 3164}, /* HALFWIDTH KATAKANA LETTER MO */
+  {0xff94, 1, 3165}, /* HALFWIDTH KATAKANA LETTER YA */
+  {0xff95, 1, 3166}, /* HALFWIDTH KATAKANA LETTER YU */
+  {0xff96, 1, 3167}, /* HALFWIDTH KATAKANA LETTER YO */
+  {0xff97, 1, 3168}, /* HALFWIDTH KATAKANA LETTER RA */
+  {0xff98, 1, 3169}, /* HALFWIDTH KATAKANA LETTER RI */
+  {0xff99, 1, 3170}, /* HALFWIDTH KATAKANA LETTER RU */
+  {0xff9a, 1, 3171}, /* HALFWIDTH KATAKANA LETTER RE */
+  {0xff9b, 1, 3172}, /* HALFWIDTH KATAKANA LETTER RO */
+  {0xff9c, 1, 2703}, /* HALFWIDTH KATAKANA LETTER WA */
+  {0xff9d, 1, 3182}, /* HALFWIDTH KATAKANA LETTER N */
+  {0xff9e, 1, 2592}, /* HALFWIDTH KATAKANA VOICED SOUND MARK */
+  {0xff9f, 1, 2624}, /* HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK */
+  {0xffa0, 1, 5058}, /* HALFWIDTH HANGUL FILLER */
+  {0xffa1, 1, 5059}, /* HALFWIDTH HANGUL LETTER KIYEOK */
+  {0xffa2, 1, 5060}, /* HALFWIDTH HANGUL LETTER SSANGKIYEOK */
+  {0xffa3, 1, 5061}, /* HALFWIDTH HANGUL LETTER KIYEOK-SIOS */
+  {0xffa4, 1, 5062}, /* HALFWIDTH HANGUL LETTER NIEUN */
+  {0xffa5, 1, 5063}, /* HALFWIDTH HANGUL LETTER NIEUN-CIEUC */
+  {0xffa6, 1, 5064}, /* HALFWIDTH HANGUL LETTER NIEUN-HIEUH */
+  {0xffa7, 1, 5065}, /* HALFWIDTH HANGUL LETTER TIKEUT */
+  {0xffa8, 1, 5066}, /* HALFWIDTH HANGUL LETTER SSANGTIKEUT */
+  {0xffa9, 1, 5067}, /* HALFWIDTH HANGUL LETTER RIEUL */
+  {0xffaa, 1, 5068}, /* HALFWIDTH HANGUL LETTER RIEUL-KIYEOK */
+  {0xffab, 1, 5069}, /* HALFWIDTH HANGUL LETTER RIEUL-MIEUM */
+  {0xffac, 1, 5070}, /* HALFWIDTH HANGUL LETTER RIEUL-PIEUP */
+  {0xffad, 1, 5071}, /* HALFWIDTH HANGUL LETTER RIEUL-SIOS */
+  {0xffae, 1, 5072}, /* HALFWIDTH HANGUL LETTER RIEUL-THIEUTH */
+  {0xffaf, 1, 5073}, /* HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH */
+  {0xffb0, 1, 5074}, /* HALFWIDTH HANGUL LETTER RIEUL-HIEUH */
+  {0xffb1, 1, 5075}, /* HALFWIDTH HANGUL LETTER MIEUM */
+  {0xffb2, 1, 5076}, /* HALFWIDTH HANGUL LETTER PIEUP */
+  {0xffb3, 1, 5077}, /* HALFWIDTH HANGUL LETTER SSANGPIEUP */
+  {0xffb4, 1, 5078}, /* HALFWIDTH HANGUL LETTER PIEUP-SIOS */
+  {0xffb5, 1, 5079}, /* HALFWIDTH HANGUL LETTER SIOS */
+  {0xffb6, 1, 5080}, /* HALFWIDTH HANGUL LETTER SSANGSIOS */
+  {0xffb7, 1, 5081}, /* HALFWIDTH HANGUL LETTER IEUNG */
+  {0xffb8, 1, 5082}, /* HALFWIDTH HANGUL LETTER CIEUC */
+  {0xffb9, 1, 5083}, /* HALFWIDTH HANGUL LETTER SSANGCIEUC */
+  {0xffba, 1, 5084}, /* HALFWIDTH HANGUL LETTER CHIEUCH */
+  {0xffbb, 1, 5085}, /* HALFWIDTH HANGUL LETTER KHIEUKH */
+  {0xffbc, 1, 5086}, /* HALFWIDTH HANGUL LETTER THIEUTH */
+  {0xffbd, 1, 5087}, /* HALFWIDTH HANGUL LETTER PHIEUPH */
+  {0xffbe, 1, 5088}, /* HALFWIDTH HANGUL LETTER HIEUH */
+  {0xffc2, 1, 5089}, /* HALFWIDTH HANGUL LETTER A */
+  {0xffc3, 1, 5090}, /* HALFWIDTH HANGUL LETTER AE */
+  {0xffc4, 1, 5091}, /* HALFWIDTH HANGUL LETTER YA */
+  {0xffc5, 1, 5092}, /* HALFWIDTH HANGUL LETTER YAE */
+  {0xffc6, 1, 5093}, /* HALFWIDTH HANGUL LETTER EO */
+  {0xffc7, 1, 5094}, /* HALFWIDTH HANGUL LETTER E */
+  {0xffca, 1, 5095}, /* HALFWIDTH HANGUL LETTER YEO */
+  {0xffcb, 1, 5096}, /* HALFWIDTH HANGUL LETTER YE */
+  {0xffcc, 1, 5097}, /* HALFWIDTH HANGUL LETTER O */
+  {0xffcd, 1, 5098}, /* HALFWIDTH HANGUL LETTER WA */
+  {0xffce, 1, 5099}, /* HALFWIDTH HANGUL LETTER WAE */
+  {0xffcf, 1, 5100}, /* HALFWIDTH HANGUL LETTER OE */
+  {0xffd2, 1, 5101}, /* HALFWIDTH HANGUL LETTER YO */
+  {0xffd3, 1, 5102}, /* HALFWIDTH HANGUL LETTER U */
+  {0xffd4, 1, 5103}, /* HALFWIDTH HANGUL LETTER WEO */
+  {0xffd5, 1, 5104}, /* HALFWIDTH HANGUL LETTER WE */
+  {0xffd6, 1, 5105}, /* HALFWIDTH HANGUL LETTER WI */
+  {0xffd7, 1, 5106}, /* HALFWIDTH HANGUL LETTER YU */
+  {0xffda, 1, 5107}, /* HALFWIDTH HANGUL LETTER EU */
+  {0xffdb, 1, 5108}, /* HALFWIDTH HANGUL LETTER YI */
+  {0xffdc, 1, 5109}, /* HALFWIDTH HANGUL LETTER I */
+  {0xffe0, 1, 5110}, /* FULLWIDTH CENT SIGN */
+  {0xffe1, 1, 5111}, /* FULLWIDTH POUND SIGN */
+  {0xffe2, 1, 5112}, /* FULLWIDTH NOT SIGN */
+  {0xffe3, 1, 5113}, /* FULLWIDTH MACRON */
+  {0xffe4, 1, 5114}, /* FULLWIDTH BROKEN BAR */
+  {0xffe5, 1, 5115}, /* FULLWIDTH YEN SIGN */
+  {0xffe6, 1, 5116}, /* FULLWIDTH WON SIGN */
+  {0xffe8, 1, 5117}, /* HALFWIDTH FORMS LIGHT VERTICAL */
+  {0xffe9, 1, 2042}, /* HALFWIDTH LEFTWARDS ARROW */
+  {0xffea, 1, 5118}, /* HALFWIDTH UPWARDS ARROW */
+  {0xffeb, 1, 2044}, /* HALFWIDTH RIGHTWARDS ARROW */
+  {0xffec, 1, 5119}, /* HALFWIDTH DOWNWARDS ARROW */
+  {0xffed, 1, 5120}, /* HALFWIDTH BLACK SQUARE */
+  {0xffee, 1, 5121}, /* HALFWIDTH WHITE CIRCLE */
+  {0x1d15e, 2, 5122}, /* MUSICAL SYMBOL HALF NOTE */
+  {0x1d15f, 2, 5124}, /* MUSICAL SYMBOL QUARTER NOTE */
+  {0x1d160, 2, 5126}, /* MUSICAL SYMBOL EIGHTH NOTE */
+  {0x1d161, 2, 5128}, /* MUSICAL SYMBOL SIXTEENTH NOTE */
+  {0x1d162, 2, 5130}, /* MUSICAL SYMBOL THIRTY-SECOND NOTE */
+  {0x1d163, 2, 5132}, /* MUSICAL SYMBOL SIXTY-FOURTH NOTE */
+  {0x1d164, 2, 5134}, /* MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE */
+  {0x1d1bb, 2, 5136}, /* MUSICAL SYMBOL MINIMA */
+  {0x1d1bc, 2, 5138}, /* MUSICAL SYMBOL MINIMA BLACK */
+  {0x1d1bd, 2, 5140}, /* MUSICAL SYMBOL SEMIMINIMA WHITE */
+  {0x1d1be, 2, 5142}, /* MUSICAL SYMBOL SEMIMINIMA BLACK */
+  {0x1d1bf, 2, 5144}, /* MUSICAL SYMBOL FUSA WHITE */
+  {0x1d1c0, 2, 5146}, /* MUSICAL SYMBOL FUSA BLACK */
+  {0x1d400, 1, 24}, /* MATHEMATICAL BOLD CAPITAL A */
+  {0x1d401, 1, 910}, /* MATHEMATICAL BOLD CAPITAL B */
+  {0x1d402, 1, 36}, /* MATHEMATICAL BOLD CAPITAL C */
+  {0x1d403, 1, 158}, /* MATHEMATICAL BOLD CAPITAL D */
+  {0x1d404, 1, 38}, /* MATHEMATICAL BOLD CAPITAL E */
+  {0x1d405, 1, 995}, /* MATHEMATICAL BOLD CAPITAL F */
+  {0x1d406, 1, 182}, /* MATHEMATICAL BOLD CAPITAL G */
+  {0x1d407, 1, 198}, /* MATHEMATICAL BOLD CAPITAL H */
+  {0x1d408, 1, 46}, /* MATHEMATICAL BOLD CAPITAL I */
+  {0x1d409, 1, 221}, /* MATHEMATICAL BOLD CAPITAL J */
+  {0x1d40a, 1, 228}, /* MATHEMATICAL BOLD CAPITAL K */
+  {0x1d40b, 1, 232}, /* MATHEMATICAL BOLD CAPITAL L */
+  {0x1d40c, 1, 912}, /* MATHEMATICAL BOLD CAPITAL M */
+  {0x1d40d, 1, 54}, /* MATHEMATICAL BOLD CAPITAL N */
+  {0x1d40e, 1, 56}, /* MATHEMATICAL BOLD CAPITAL O */
+  {0x1d40f, 1, 914}, /* MATHEMATICAL BOLD CAPITAL P */
+  {0x1d410, 1, 1942}, /* MATHEMATICAL BOLD CAPITAL Q */
+  {0x1d411, 1, 274}, /* MATHEMATICAL BOLD CAPITAL R */
+  {0x1d412, 1, 286}, /* MATHEMATICAL BOLD CAPITAL S */
+  {0x1d413, 1, 302}, /* MATHEMATICAL BOLD CAPITAL T */
+  {0x1d414, 1, 66}, /* MATHEMATICAL BOLD CAPITAL U */
+  {0x1d415, 1, 1183}, /* MATHEMATICAL BOLD CAPITAL V */
+  {0x1d416, 1, 334}, /* MATHEMATICAL BOLD CAPITAL W */
+  {0x1d417, 1, 1211}, /* MATHEMATICAL BOLD CAPITAL X */
+  {0x1d418, 1, 74}, /* MATHEMATICAL BOLD CAPITAL Y */
+  {0x1d419, 1, 344}, /* MATHEMATICAL BOLD CAPITAL Z */
+  {0x1d41a, 1, 3}, /* MATHEMATICAL BOLD SMALL A */
+  {0x1d41b, 1, 918}, /* MATHEMATICAL BOLD SMALL B */
+  {0x1d41c, 1, 88}, /* MATHEMATICAL BOLD SMALL C */
+  {0x1d41d, 1, 160}, /* MATHEMATICAL BOLD SMALL D */
+  {0x1d41e, 1, 90}, /* MATHEMATICAL BOLD SMALL E */
+  {0x1d41f, 1, 997}, /* MATHEMATICAL BOLD SMALL F */
+  {0x1d420, 1, 184}, /* MATHEMATICAL BOLD SMALL G */
+  {0x1d421, 1, 200}, /* MATHEMATICAL BOLD SMALL H */
+  {0x1d422, 1, 98}, /* MATHEMATICAL BOLD SMALL I */
+  {0x1d423, 1, 223}, /* MATHEMATICAL BOLD SMALL J */
+  {0x1d424, 1, 230}, /* MATHEMATICAL BOLD SMALL K */
+  {0x1d425, 1, 234}, /* MATHEMATICAL BOLD SMALL L */
+  {0x1d426, 1, 922}, /* MATHEMATICAL BOLD SMALL M */
+  {0x1d427, 1, 106}, /* MATHEMATICAL BOLD SMALL N */
+  {0x1d428, 1, 14}, /* MATHEMATICAL BOLD SMALL O */
+  {0x1d429, 1, 927}, /* MATHEMATICAL BOLD SMALL P */
+  {0x1d42a, 1, 2335}, /* MATHEMATICAL BOLD SMALL Q */
+  {0x1d42b, 1, 276}, /* MATHEMATICAL BOLD SMALL R */
+  {0x1d42c, 1, 288}, /* MATHEMATICAL BOLD SMALL S */
+  {0x1d42d, 1, 304}, /* MATHEMATICAL BOLD SMALL T */
+  {0x1d42e, 1, 118}, /* MATHEMATICAL BOLD SMALL U */
+  {0x1d42f, 1, 930}, /* MATHEMATICAL BOLD SMALL V */
+  {0x1d430, 1, 336}, /* MATHEMATICAL BOLD SMALL W */
+  {0x1d431, 1, 579}, /* MATHEMATICAL BOLD SMALL X */
+  {0x1d432, 1, 126}, /* MATHEMATICAL BOLD SMALL Y */
+  {0x1d433, 1, 346}, /* MATHEMATICAL BOLD SMALL Z */
+  {0x1d434, 1, 24}, /* MATHEMATICAL ITALIC CAPITAL A */
+  {0x1d435, 1, 910}, /* MATHEMATICAL ITALIC CAPITAL B */
+  {0x1d436, 1, 36}, /* MATHEMATICAL ITALIC CAPITAL C */
+  {0x1d437, 1, 158}, /* MATHEMATICAL ITALIC CAPITAL D */
+  {0x1d438, 1, 38}, /* MATHEMATICAL ITALIC CAPITAL E */
+  {0x1d439, 1, 995}, /* MATHEMATICAL ITALIC CAPITAL F */
+  {0x1d43a, 1, 182}, /* MATHEMATICAL ITALIC CAPITAL G */
+  {0x1d43b, 1, 198}, /* MATHEMATICAL ITALIC CAPITAL H */
+  {0x1d43c, 1, 46}, /* MATHEMATICAL ITALIC CAPITAL I */
+  {0x1d43d, 1, 221}, /* MATHEMATICAL ITALIC CAPITAL J */
+  {0x1d43e, 1, 228}, /* MATHEMATICAL ITALIC CAPITAL K */
+  {0x1d43f, 1, 232}, /* MATHEMATICAL ITALIC CAPITAL L */
+  {0x1d440, 1, 912}, /* MATHEMATICAL ITALIC CAPITAL M */
+  {0x1d441, 1, 54}, /* MATHEMATICAL ITALIC CAPITAL N */
+  {0x1d442, 1, 56}, /* MATHEMATICAL ITALIC CAPITAL O */
+  {0x1d443, 1, 914}, /* MATHEMATICAL ITALIC CAPITAL P */
+  {0x1d444, 1, 1942}, /* MATHEMATICAL ITALIC CAPITAL Q */
+  {0x1d445, 1, 274}, /* MATHEMATICAL ITALIC CAPITAL R */
+  {0x1d446, 1, 286}, /* MATHEMATICAL ITALIC CAPITAL S */
+  {0x1d447, 1, 302}, /* MATHEMATICAL ITALIC CAPITAL T */
+  {0x1d448, 1, 66}, /* MATHEMATICAL ITALIC CAPITAL U */
+  {0x1d449, 1, 1183}, /* MATHEMATICAL ITALIC CAPITAL V */
+  {0x1d44a, 1, 334}, /* MATHEMATICAL ITALIC CAPITAL W */
+  {0x1d44b, 1, 1211}, /* MATHEMATICAL ITALIC CAPITAL X */
+  {0x1d44c, 1, 74}, /* MATHEMATICAL ITALIC CAPITAL Y */
+  {0x1d44d, 1, 344}, /* MATHEMATICAL ITALIC CAPITAL Z */
+  {0x1d44e, 1, 3}, /* MATHEMATICAL ITALIC SMALL A */
+  {0x1d44f, 1, 918}, /* MATHEMATICAL ITALIC SMALL B */
+  {0x1d450, 1, 88}, /* MATHEMATICAL ITALIC SMALL C */
+  {0x1d451, 1, 160}, /* MATHEMATICAL ITALIC SMALL D */
+  {0x1d452, 1, 90}, /* MATHEMATICAL ITALIC SMALL E */
+  {0x1d453, 1, 997}, /* MATHEMATICAL ITALIC SMALL F */
+  {0x1d454, 1, 184}, /* MATHEMATICAL ITALIC SMALL G */
+  {0x1d456, 1, 98}, /* MATHEMATICAL ITALIC SMALL I */
+  {0x1d457, 1, 223}, /* MATHEMATICAL ITALIC SMALL J */
+  {0x1d458, 1, 230}, /* MATHEMATICAL ITALIC SMALL K */
+  {0x1d459, 1, 234}, /* MATHEMATICAL ITALIC SMALL L */
+  {0x1d45a, 1, 922}, /* MATHEMATICAL ITALIC SMALL M */
+  {0x1d45b, 1, 106}, /* MATHEMATICAL ITALIC SMALL N */
+  {0x1d45c, 1, 14}, /* MATHEMATICAL ITALIC SMALL O */
+  {0x1d45d, 1, 927}, /* MATHEMATICAL ITALIC SMALL P */
+  {0x1d45e, 1, 2335}, /* MATHEMATICAL ITALIC SMALL Q */
+  {0x1d45f, 1, 276}, /* MATHEMATICAL ITALIC SMALL R */
+  {0x1d460, 1, 288}, /* MATHEMATICAL ITALIC SMALL S */
+  {0x1d461, 1, 304}, /* MATHEMATICAL ITALIC SMALL T */
+  {0x1d462, 1, 118}, /* MATHEMATICAL ITALIC SMALL U */
+  {0x1d463, 1, 930}, /* MATHEMATICAL ITALIC SMALL V */
+  {0x1d464, 1, 336}, /* MATHEMATICAL ITALIC SMALL W */
+  {0x1d465, 1, 579}, /* MATHEMATICAL ITALIC SMALL X */
+  {0x1d466, 1, 126}, /* MATHEMATICAL ITALIC SMALL Y */
+  {0x1d467, 1, 346}, /* MATHEMATICAL ITALIC SMALL Z */
+  {0x1d468, 1, 24}, /* MATHEMATICAL BOLD ITALIC CAPITAL A */
+  {0x1d469, 1, 910}, /* MATHEMATICAL BOLD ITALIC CAPITAL B */
+  {0x1d46a, 1, 36}, /* MATHEMATICAL BOLD ITALIC CAPITAL C */
+  {0x1d46b, 1, 158}, /* MATHEMATICAL BOLD ITALIC CAPITAL D */
+  {0x1d46c, 1, 38}, /* MATHEMATICAL BOLD ITALIC CAPITAL E */
+  {0x1d46d, 1, 995}, /* MATHEMATICAL BOLD ITALIC CAPITAL F */
+  {0x1d46e, 1, 182}, /* MATHEMATICAL BOLD ITALIC CAPITAL G */
+  {0x1d46f, 1, 198}, /* MATHEMATICAL BOLD ITALIC CAPITAL H */
+  {0x1d470, 1, 46}, /* MATHEMATICAL BOLD ITALIC CAPITAL I */
+  {0x1d471, 1, 221}, /* MATHEMATICAL BOLD ITALIC CAPITAL J */
+  {0x1d472, 1, 228}, /* MATHEMATICAL BOLD ITALIC CAPITAL K */
+  {0x1d473, 1, 232}, /* MATHEMATICAL BOLD ITALIC CAPITAL L */
+  {0x1d474, 1, 912}, /* MATHEMATICAL BOLD ITALIC CAPITAL M */
+  {0x1d475, 1, 54}, /* MATHEMATICAL BOLD ITALIC CAPITAL N */
+  {0x1d476, 1, 56}, /* MATHEMATICAL BOLD ITALIC CAPITAL O */
+  {0x1d477, 1, 914}, /* MATHEMATICAL BOLD ITALIC CAPITAL P */
+  {0x1d478, 1, 1942}, /* MATHEMATICAL BOLD ITALIC CAPITAL Q */
+  {0x1d479, 1, 274}, /* MATHEMATICAL BOLD ITALIC CAPITAL R */
+  {0x1d47a, 1, 286}, /* MATHEMATICAL BOLD ITALIC CAPITAL S */
+  {0x1d47b, 1, 302}, /* MATHEMATICAL BOLD ITALIC CAPITAL T */
+  {0x1d47c, 1, 66}, /* MATHEMATICAL BOLD ITALIC CAPITAL U */
+  {0x1d47d, 1, 1183}, /* MATHEMATICAL BOLD ITALIC CAPITAL V */
+  {0x1d47e, 1, 334}, /* MATHEMATICAL BOLD ITALIC CAPITAL W */
+  {0x1d47f, 1, 1211}, /* MATHEMATICAL BOLD ITALIC CAPITAL X */
+  {0x1d480, 1, 74}, /* MATHEMATICAL BOLD ITALIC CAPITAL Y */
+  {0x1d481, 1, 344}, /* MATHEMATICAL BOLD ITALIC CAPITAL Z */
+  {0x1d482, 1, 3}, /* MATHEMATICAL BOLD ITALIC SMALL A */
+  {0x1d483, 1, 918}, /* MATHEMATICAL BOLD ITALIC SMALL B */
+  {0x1d484, 1, 88}, /* MATHEMATICAL BOLD ITALIC SMALL C */
+  {0x1d485, 1, 160}, /* MATHEMATICAL BOLD ITALIC SMALL D */
+  {0x1d486, 1, 90}, /* MATHEMATICAL BOLD ITALIC SMALL E */
+  {0x1d487, 1, 997}, /* MATHEMATICAL BOLD ITALIC SMALL F */
+  {0x1d488, 1, 184}, /* MATHEMATICAL BOLD ITALIC SMALL G */
+  {0x1d489, 1, 200}, /* MATHEMATICAL BOLD ITALIC SMALL H */
+  {0x1d48a, 1, 98}, /* MATHEMATICAL BOLD ITALIC SMALL I */
+  {0x1d48b, 1, 223}, /* MATHEMATICAL BOLD ITALIC SMALL J */
+  {0x1d48c, 1, 230}, /* MATHEMATICAL BOLD ITALIC SMALL K */
+  {0x1d48d, 1, 234}, /* MATHEMATICAL BOLD ITALIC SMALL L */
+  {0x1d48e, 1, 922}, /* MATHEMATICAL BOLD ITALIC SMALL M */
+  {0x1d48f, 1, 106}, /* MATHEMATICAL BOLD ITALIC SMALL N */
+  {0x1d490, 1, 14}, /* MATHEMATICAL BOLD ITALIC SMALL O */
+  {0x1d491, 1, 927}, /* MATHEMATICAL BOLD ITALIC SMALL P */
+  {0x1d492, 1, 2335}, /* MATHEMATICAL BOLD ITALIC SMALL Q */
+  {0x1d493, 1, 276}, /* MATHEMATICAL BOLD ITALIC SMALL R */
+  {0x1d494, 1, 288}, /* MATHEMATICAL BOLD ITALIC SMALL S */
+  {0x1d495, 1, 304}, /* MATHEMATICAL BOLD ITALIC SMALL T */
+  {0x1d496, 1, 118}, /* MATHEMATICAL BOLD ITALIC SMALL U */
+  {0x1d497, 1, 930}, /* MATHEMATICAL BOLD ITALIC SMALL V */
+  {0x1d498, 1, 336}, /* MATHEMATICAL BOLD ITALIC SMALL W */
+  {0x1d499, 1, 579}, /* MATHEMATICAL BOLD ITALIC SMALL X */
+  {0x1d49a, 1, 126}, /* MATHEMATICAL BOLD ITALIC SMALL Y */
+  {0x1d49b, 1, 346}, /* MATHEMATICAL BOLD ITALIC SMALL Z */
+  {0x1d49c, 1, 24}, /* MATHEMATICAL SCRIPT CAPITAL A */
+  {0x1d49e, 1, 36}, /* MATHEMATICAL SCRIPT CAPITAL C */
+  {0x1d49f, 1, 158}, /* MATHEMATICAL SCRIPT CAPITAL D */
+  {0x1d4a2, 1, 182}, /* MATHEMATICAL SCRIPT CAPITAL G */
+  {0x1d4a5, 1, 221}, /* MATHEMATICAL SCRIPT CAPITAL J */
+  {0x1d4a6, 1, 228}, /* MATHEMATICAL SCRIPT CAPITAL K */
+  {0x1d4a9, 1, 54}, /* MATHEMATICAL SCRIPT CAPITAL N */
+  {0x1d4aa, 1, 56}, /* MATHEMATICAL SCRIPT CAPITAL O */
+  {0x1d4ab, 1, 914}, /* MATHEMATICAL SCRIPT CAPITAL P */
+  {0x1d4ac, 1, 1942}, /* MATHEMATICAL SCRIPT CAPITAL Q */
+  {0x1d4ae, 1, 286}, /* MATHEMATICAL SCRIPT CAPITAL S */
+  {0x1d4af, 1, 302}, /* MATHEMATICAL SCRIPT CAPITAL T */
+  {0x1d4b0, 1, 66}, /* MATHEMATICAL SCRIPT CAPITAL U */
+  {0x1d4b1, 1, 1183}, /* MATHEMATICAL SCRIPT CAPITAL V */
+  {0x1d4b2, 1, 334}, /* MATHEMATICAL SCRIPT CAPITAL W */
+  {0x1d4b3, 1, 1211}, /* MATHEMATICAL SCRIPT CAPITAL X */
+  {0x1d4b4, 1, 74}, /* MATHEMATICAL SCRIPT CAPITAL Y */
+  {0x1d4b5, 1, 344}, /* MATHEMATICAL SCRIPT CAPITAL Z */
+  {0x1d4b6, 1, 3}, /* MATHEMATICAL SCRIPT SMALL A */
+  {0x1d4b7, 1, 918}, /* MATHEMATICAL SCRIPT SMALL B */
+  {0x1d4b8, 1, 88}, /* MATHEMATICAL SCRIPT SMALL C */
+  {0x1d4b9, 1, 160}, /* MATHEMATICAL SCRIPT SMALL D */
+  {0x1d4bb, 1, 997}, /* MATHEMATICAL SCRIPT SMALL F */
+  {0x1d4bd, 1, 200}, /* MATHEMATICAL SCRIPT SMALL H */
+  {0x1d4be, 1, 98}, /* MATHEMATICAL SCRIPT SMALL I */
+  {0x1d4bf, 1, 223}, /* MATHEMATICAL SCRIPT SMALL J */
+  {0x1d4c0, 1, 230}, /* MATHEMATICAL SCRIPT SMALL K */
+  {0x1d4c1, 1, 234}, /* MATHEMATICAL SCRIPT SMALL L */
+  {0x1d4c2, 1, 922}, /* MATHEMATICAL SCRIPT SMALL M */
+  {0x1d4c3, 1, 106}, /* MATHEMATICAL SCRIPT SMALL N */
+  {0x1d4c5, 1, 927}, /* MATHEMATICAL SCRIPT SMALL P */
+  {0x1d4c6, 1, 2335}, /* MATHEMATICAL SCRIPT SMALL Q */
+  {0x1d4c7, 1, 276}, /* MATHEMATICAL SCRIPT SMALL R */
+  {0x1d4c8, 1, 288}, /* MATHEMATICAL SCRIPT SMALL S */
+  {0x1d4c9, 1, 304}, /* MATHEMATICAL SCRIPT SMALL T */
+  {0x1d4ca, 1, 118}, /* MATHEMATICAL SCRIPT SMALL U */
+  {0x1d4cb, 1, 930}, /* MATHEMATICAL SCRIPT SMALL V */
+  {0x1d4cc, 1, 336}, /* MATHEMATICAL SCRIPT SMALL W */
+  {0x1d4cd, 1, 579}, /* MATHEMATICAL SCRIPT SMALL X */
+  {0x1d4ce, 1, 126}, /* MATHEMATICAL SCRIPT SMALL Y */
+  {0x1d4cf, 1, 346}, /* MATHEMATICAL SCRIPT SMALL Z */
+  {0x1d4d0, 1, 24}, /* MATHEMATICAL BOLD SCRIPT CAPITAL A */
+  {0x1d4d1, 1, 910}, /* MATHEMATICAL BOLD SCRIPT CAPITAL B */
+  {0x1d4d2, 1, 36}, /* MATHEMATICAL BOLD SCRIPT CAPITAL C */
+  {0x1d4d3, 1, 158}, /* MATHEMATICAL BOLD SCRIPT CAPITAL D */
+  {0x1d4d4, 1, 38}, /* MATHEMATICAL BOLD SCRIPT CAPITAL E */
+  {0x1d4d5, 1, 995}, /* MATHEMATICAL BOLD SCRIPT CAPITAL F */
+  {0x1d4d6, 1, 182}, /* MATHEMATICAL BOLD SCRIPT CAPITAL G */
+  {0x1d4d7, 1, 198}, /* MATHEMATICAL BOLD SCRIPT CAPITAL H */
+  {0x1d4d8, 1, 46}, /* MATHEMATICAL BOLD SCRIPT CAPITAL I */
+  {0x1d4d9, 1, 221}, /* MATHEMATICAL BOLD SCRIPT CAPITAL J */
+  {0x1d4da, 1, 228}, /* MATHEMATICAL BOLD SCRIPT CAPITAL K */
+  {0x1d4db, 1, 232}, /* MATHEMATICAL BOLD SCRIPT CAPITAL L */
+  {0x1d4dc, 1, 912}, /* MATHEMATICAL BOLD SCRIPT CAPITAL M */
+  {0x1d4dd, 1, 54}, /* MATHEMATICAL BOLD SCRIPT CAPITAL N */
+  {0x1d4de, 1, 56}, /* MATHEMATICAL BOLD SCRIPT CAPITAL O */
+  {0x1d4df, 1, 914}, /* MATHEMATICAL BOLD SCRIPT CAPITAL P */
+  {0x1d4e0, 1, 1942}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Q */
+  {0x1d4e1, 1, 274}, /* MATHEMATICAL BOLD SCRIPT CAPITAL R */
+  {0x1d4e2, 1, 286}, /* MATHEMATICAL BOLD SCRIPT CAPITAL S */
+  {0x1d4e3, 1, 302}, /* MATHEMATICAL BOLD SCRIPT CAPITAL T */
+  {0x1d4e4, 1, 66}, /* MATHEMATICAL BOLD SCRIPT CAPITAL U */
+  {0x1d4e5, 1, 1183}, /* MATHEMATICAL BOLD SCRIPT CAPITAL V */
+  {0x1d4e6, 1, 334}, /* MATHEMATICAL BOLD SCRIPT CAPITAL W */
+  {0x1d4e7, 1, 1211}, /* MATHEMATICAL BOLD SCRIPT CAPITAL X */
+  {0x1d4e8, 1, 74}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Y */
+  {0x1d4e9, 1, 344}, /* MATHEMATICAL BOLD SCRIPT CAPITAL Z */
+  {0x1d4ea, 1, 3}, /* MATHEMATICAL BOLD SCRIPT SMALL A */
+  {0x1d4eb, 1, 918}, /* MATHEMATICAL BOLD SCRIPT SMALL B */
+  {0x1d4ec, 1, 88}, /* MATHEMATICAL BOLD SCRIPT SMALL C */
+  {0x1d4ed, 1, 160}, /* MATHEMATICAL BOLD SCRIPT SMALL D */
+  {0x1d4ee, 1, 90}, /* MATHEMATICAL BOLD SCRIPT SMALL E */
+  {0x1d4ef, 1, 997}, /* MATHEMATICAL BOLD SCRIPT SMALL F */
+  {0x1d4f0, 1, 184}, /* MATHEMATICAL BOLD SCRIPT SMALL G */
+  {0x1d4f1, 1, 200}, /* MATHEMATICAL BOLD SCRIPT SMALL H */
+  {0x1d4f2, 1, 98}, /* MATHEMATICAL BOLD SCRIPT SMALL I */
+  {0x1d4f3, 1, 223}, /* MATHEMATICAL BOLD SCRIPT SMALL J */
+  {0x1d4f4, 1, 230}, /* MATHEMATICAL BOLD SCRIPT SMALL K */
+  {0x1d4f5, 1, 234}, /* MATHEMATICAL BOLD SCRIPT SMALL L */
+  {0x1d4f6, 1, 922}, /* MATHEMATICAL BOLD SCRIPT SMALL M */
+  {0x1d4f7, 1, 106}, /* MATHEMATICAL BOLD SCRIPT SMALL N */
+  {0x1d4f8, 1, 14}, /* MATHEMATICAL BOLD SCRIPT SMALL O */
+  {0x1d4f9, 1, 927}, /* MATHEMATICAL BOLD SCRIPT SMALL P */
+  {0x1d4fa, 1, 2335}, /* MATHEMATICAL BOLD SCRIPT SMALL Q */
+  {0x1d4fb, 1, 276}, /* MATHEMATICAL BOLD SCRIPT SMALL R */
+  {0x1d4fc, 1, 288}, /* MATHEMATICAL BOLD SCRIPT SMALL S */
+  {0x1d4fd, 1, 304}, /* MATHEMATICAL BOLD SCRIPT SMALL T */
+  {0x1d4fe, 1, 118}, /* MATHEMATICAL BOLD SCRIPT SMALL U */
+  {0x1d4ff, 1, 930}, /* MATHEMATICAL BOLD SCRIPT SMALL V */
+  {0x1d500, 1, 336}, /* MATHEMATICAL BOLD SCRIPT SMALL W */
+  {0x1d501, 1, 579}, /* MATHEMATICAL BOLD SCRIPT SMALL X */
+  {0x1d502, 1, 126}, /* MATHEMATICAL BOLD SCRIPT SMALL Y */
+  {0x1d503, 1, 346}, /* MATHEMATICAL BOLD SCRIPT SMALL Z */
+  {0x1d504, 1, 24}, /* MATHEMATICAL FRAKTUR CAPITAL A */
+  {0x1d505, 1, 910}, /* MATHEMATICAL FRAKTUR CAPITAL B */
+  {0x1d507, 1, 158}, /* MATHEMATICAL FRAKTUR CAPITAL D */
+  {0x1d508, 1, 38}, /* MATHEMATICAL FRAKTUR CAPITAL E */
+  {0x1d509, 1, 995}, /* MATHEMATICAL FRAKTUR CAPITAL F */
+  {0x1d50a, 1, 182}, /* MATHEMATICAL FRAKTUR CAPITAL G */
+  {0x1d50d, 1, 221}, /* MATHEMATICAL FRAKTUR CAPITAL J */
+  {0x1d50e, 1, 228}, /* MATHEMATICAL FRAKTUR CAPITAL K */
+  {0x1d50f, 1, 232}, /* MATHEMATICAL FRAKTUR CAPITAL L */
+  {0x1d510, 1, 912}, /* MATHEMATICAL FRAKTUR CAPITAL M */
+  {0x1d511, 1, 54}, /* MATHEMATICAL FRAKTUR CAPITAL N */
+  {0x1d512, 1, 56}, /* MATHEMATICAL FRAKTUR CAPITAL O */
+  {0x1d513, 1, 914}, /* MATHEMATICAL FRAKTUR CAPITAL P */
+  {0x1d514, 1, 1942}, /* MATHEMATICAL FRAKTUR CAPITAL Q */
+  {0x1d516, 1, 286}, /* MATHEMATICAL FRAKTUR CAPITAL S */
+  {0x1d517, 1, 302}, /* MATHEMATICAL FRAKTUR CAPITAL T */
+  {0x1d518, 1, 66}, /* MATHEMATICAL FRAKTUR CAPITAL U */
+  {0x1d519, 1, 1183}, /* MATHEMATICAL FRAKTUR CAPITAL V */
+  {0x1d51a, 1, 334}, /* MATHEMATICAL FRAKTUR CAPITAL W */
+  {0x1d51b, 1, 1211}, /* MATHEMATICAL FRAKTUR CAPITAL X */
+  {0x1d51c, 1, 74}, /* MATHEMATICAL FRAKTUR CAPITAL Y */
+  {0x1d51e, 1, 3}, /* MATHEMATICAL FRAKTUR SMALL A */
+  {0x1d51f, 1, 918}, /* MATHEMATICAL FRAKTUR SMALL B */
+  {0x1d520, 1, 88}, /* MATHEMATICAL FRAKTUR SMALL C */
+  {0x1d521, 1, 160}, /* MATHEMATICAL FRAKTUR SMALL D */
+  {0x1d522, 1, 90}, /* MATHEMATICAL FRAKTUR SMALL E */
+  {0x1d523, 1, 997}, /* MATHEMATICAL FRAKTUR SMALL F */
+  {0x1d524, 1, 184}, /* MATHEMATICAL FRAKTUR SMALL G */
+  {0x1d525, 1, 200}, /* MATHEMATICAL FRAKTUR SMALL H */
+  {0x1d526, 1, 98}, /* MATHEMATICAL FRAKTUR SMALL I */
+  {0x1d527, 1, 223}, /* MATHEMATICAL FRAKTUR SMALL J */
+  {0x1d528, 1, 230}, /* MATHEMATICAL FRAKTUR SMALL K */
+  {0x1d529, 1, 234}, /* MATHEMATICAL FRAKTUR SMALL L */
+  {0x1d52a, 1, 922}, /* MATHEMATICAL FRAKTUR SMALL M */
+  {0x1d52b, 1, 106}, /* MATHEMATICAL FRAKTUR SMALL N */
+  {0x1d52c, 1, 14}, /* MATHEMATICAL FRAKTUR SMALL O */
+  {0x1d52d, 1, 927}, /* MATHEMATICAL FRAKTUR SMALL P */
+  {0x1d52e, 1, 2335}, /* MATHEMATICAL FRAKTUR SMALL Q */
+  {0x1d52f, 1, 276}, /* MATHEMATICAL FRAKTUR SMALL R */
+  {0x1d530, 1, 288}, /* MATHEMATICAL FRAKTUR SMALL S */
+  {0x1d531, 1, 304}, /* MATHEMATICAL FRAKTUR SMALL T */
+  {0x1d532, 1, 118}, /* MATHEMATICAL FRAKTUR SMALL U */
+  {0x1d533, 1, 930}, /* MATHEMATICAL FRAKTUR SMALL V */
+  {0x1d534, 1, 336}, /* MATHEMATICAL FRAKTUR SMALL W */
+  {0x1d535, 1, 579}, /* MATHEMATICAL FRAKTUR SMALL X */
+  {0x1d536, 1, 126}, /* MATHEMATICAL FRAKTUR SMALL Y */
+  {0x1d537, 1, 346}, /* MATHEMATICAL FRAKTUR SMALL Z */
+  {0x1d538, 1, 24}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL A */
+  {0x1d539, 1, 910}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL B */
+  {0x1d53b, 1, 158}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL D */
+  {0x1d53c, 1, 38}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL E */
+  {0x1d53d, 1, 995}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL F */
+  {0x1d53e, 1, 182}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL G */
+  {0x1d540, 1, 46}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL I */
+  {0x1d541, 1, 221}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL J */
+  {0x1d542, 1, 228}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL K */
+  {0x1d543, 1, 232}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL L */
+  {0x1d544, 1, 912}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL M */
+  {0x1d546, 1, 56}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL O */
+  {0x1d54a, 1, 286}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL S */
+  {0x1d54b, 1, 302}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL T */
+  {0x1d54c, 1, 66}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL U */
+  {0x1d54d, 1, 1183}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL V */
+  {0x1d54e, 1, 334}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL W */
+  {0x1d54f, 1, 1211}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL X */
+  {0x1d550, 1, 74}, /* MATHEMATICAL DOUBLE-STRUCK CAPITAL Y */
+  {0x1d552, 1, 3}, /* MATHEMATICAL DOUBLE-STRUCK SMALL A */
+  {0x1d553, 1, 918}, /* MATHEMATICAL DOUBLE-STRUCK SMALL B */
+  {0x1d554, 1, 88}, /* MATHEMATICAL DOUBLE-STRUCK SMALL C */
+  {0x1d555, 1, 160}, /* MATHEMATICAL DOUBLE-STRUCK SMALL D */
+  {0x1d556, 1, 90}, /* MATHEMATICAL DOUBLE-STRUCK SMALL E */
+  {0x1d557, 1, 997}, /* MATHEMATICAL DOUBLE-STRUCK SMALL F */
+  {0x1d558, 1, 184}, /* MATHEMATICAL DOUBLE-STRUCK SMALL G */
+  {0x1d559, 1, 200}, /* MATHEMATICAL DOUBLE-STRUCK SMALL H */
+  {0x1d55a, 1, 98}, /* MATHEMATICAL DOUBLE-STRUCK SMALL I */
+  {0x1d55b, 1, 223}, /* MATHEMATICAL DOUBLE-STRUCK SMALL J */
+  {0x1d55c, 1, 230}, /* MATHEMATICAL DOUBLE-STRUCK SMALL K */
+  {0x1d55d, 1, 234}, /* MATHEMATICAL DOUBLE-STRUCK SMALL L */
+  {0x1d55e, 1, 922}, /* MATHEMATICAL DOUBLE-STRUCK SMALL M */
+  {0x1d55f, 1, 106}, /* MATHEMATICAL DOUBLE-STRUCK SMALL N */
+  {0x1d560, 1, 14}, /* MATHEMATICAL DOUBLE-STRUCK SMALL O */
+  {0x1d561, 1, 927}, /* MATHEMATICAL DOUBLE-STRUCK SMALL P */
+  {0x1d562, 1, 2335}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Q */
+  {0x1d563, 1, 276}, /* MATHEMATICAL DOUBLE-STRUCK SMALL R */
+  {0x1d564, 1, 288}, /* MATHEMATICAL DOUBLE-STRUCK SMALL S */
+  {0x1d565, 1, 304}, /* MATHEMATICAL DOUBLE-STRUCK SMALL T */
+  {0x1d566, 1, 118}, /* MATHEMATICAL DOUBLE-STRUCK SMALL U */
+  {0x1d567, 1, 930}, /* MATHEMATICAL DOUBLE-STRUCK SMALL V */
+  {0x1d568, 1, 336}, /* MATHEMATICAL DOUBLE-STRUCK SMALL W */
+  {0x1d569, 1, 579}, /* MATHEMATICAL DOUBLE-STRUCK SMALL X */
+  {0x1d56a, 1, 126}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Y */
+  {0x1d56b, 1, 346}, /* MATHEMATICAL DOUBLE-STRUCK SMALL Z */
+  {0x1d56c, 1, 24}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL A */
+  {0x1d56d, 1, 910}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL B */
+  {0x1d56e, 1, 36}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL C */
+  {0x1d56f, 1, 158}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL D */
+  {0x1d570, 1, 38}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL E */
+  {0x1d571, 1, 995}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL F */
+  {0x1d572, 1, 182}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL G */
+  {0x1d573, 1, 198}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL H */
+  {0x1d574, 1, 46}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL I */
+  {0x1d575, 1, 221}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL J */
+  {0x1d576, 1, 228}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL K */
+  {0x1d577, 1, 232}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL L */
+  {0x1d578, 1, 912}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL M */
+  {0x1d579, 1, 54}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL N */
+  {0x1d57a, 1, 56}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL O */
+  {0x1d57b, 1, 914}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL P */
+  {0x1d57c, 1, 1942}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Q */
+  {0x1d57d, 1, 274}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL R */
+  {0x1d57e, 1, 286}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL S */
+  {0x1d57f, 1, 302}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL T */
+  {0x1d580, 1, 66}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL U */
+  {0x1d581, 1, 1183}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL V */
+  {0x1d582, 1, 334}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL W */
+  {0x1d583, 1, 1211}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL X */
+  {0x1d584, 1, 74}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Y */
+  {0x1d585, 1, 344}, /* MATHEMATICAL BOLD FRAKTUR CAPITAL Z */
+  {0x1d586, 1, 3}, /* MATHEMATICAL BOLD FRAKTUR SMALL A */
+  {0x1d587, 1, 918}, /* MATHEMATICAL BOLD FRAKTUR SMALL B */
+  {0x1d588, 1, 88}, /* MATHEMATICAL BOLD FRAKTUR SMALL C */
+  {0x1d589, 1, 160}, /* MATHEMATICAL BOLD FRAKTUR SMALL D */
+  {0x1d58a, 1, 90}, /* MATHEMATICAL BOLD FRAKTUR SMALL E */
+  {0x1d58b, 1, 997}, /* MATHEMATICAL BOLD FRAKTUR SMALL F */
+  {0x1d58c, 1, 184}, /* MATHEMATICAL BOLD FRAKTUR SMALL G */
+  {0x1d58d, 1, 200}, /* MATHEMATICAL BOLD FRAKTUR SMALL H */
+  {0x1d58e, 1, 98}, /* MATHEMATICAL BOLD FRAKTUR SMALL I */
+  {0x1d58f, 1, 223}, /* MATHEMATICAL BOLD FRAKTUR SMALL J */
+  {0x1d590, 1, 230}, /* MATHEMATICAL BOLD FRAKTUR SMALL K */
+  {0x1d591, 1, 234}, /* MATHEMATICAL BOLD FRAKTUR SMALL L */
+  {0x1d592, 1, 922}, /* MATHEMATICAL BOLD FRAKTUR SMALL M */
+  {0x1d593, 1, 106}, /* MATHEMATICAL BOLD FRAKTUR SMALL N */
+  {0x1d594, 1, 14}, /* MATHEMATICAL BOLD FRAKTUR SMALL O */
+  {0x1d595, 1, 927}, /* MATHEMATICAL BOLD FRAKTUR SMALL P */
+  {0x1d596, 1, 2335}, /* MATHEMATICAL BOLD FRAKTUR SMALL Q */
+  {0x1d597, 1, 276}, /* MATHEMATICAL BOLD FRAKTUR SMALL R */
+  {0x1d598, 1, 288}, /* MATHEMATICAL BOLD FRAKTUR SMALL S */
+  {0x1d599, 1, 304}, /* MATHEMATICAL BOLD FRAKTUR SMALL T */
+  {0x1d59a, 1, 118}, /* MATHEMATICAL BOLD FRAKTUR SMALL U */
+  {0x1d59b, 1, 930}, /* MATHEMATICAL BOLD FRAKTUR SMALL V */
+  {0x1d59c, 1, 336}, /* MATHEMATICAL BOLD FRAKTUR SMALL W */
+  {0x1d59d, 1, 579}, /* MATHEMATICAL BOLD FRAKTUR SMALL X */
+  {0x1d59e, 1, 126}, /* MATHEMATICAL BOLD FRAKTUR SMALL Y */
+  {0x1d59f, 1, 346}, /* MATHEMATICAL BOLD FRAKTUR SMALL Z */
+  {0x1d5a0, 1, 24}, /* MATHEMATICAL SANS-SERIF CAPITAL A */
+  {0x1d5a1, 1, 910}, /* MATHEMATICAL SANS-SERIF CAPITAL B */
+  {0x1d5a2, 1, 36}, /* MATHEMATICAL SANS-SERIF CAPITAL C */
+  {0x1d5a3, 1, 158}, /* MATHEMATICAL SANS-SERIF CAPITAL D */
+  {0x1d5a4, 1, 38}, /* MATHEMATICAL SANS-SERIF CAPITAL E */
+  {0x1d5a5, 1, 995}, /* MATHEMATICAL SANS-SERIF CAPITAL F */
+  {0x1d5a6, 1, 182}, /* MATHEMATICAL SANS-SERIF CAPITAL G */
+  {0x1d5a7, 1, 198}, /* MATHEMATICAL SANS-SERIF CAPITAL H */
+  {0x1d5a8, 1, 46}, /* MATHEMATICAL SANS-SERIF CAPITAL I */
+  {0x1d5a9, 1, 221}, /* MATHEMATICAL SANS-SERIF CAPITAL J */
+  {0x1d5aa, 1, 228}, /* MATHEMATICAL SANS-SERIF CAPITAL K */
+  {0x1d5ab, 1, 232}, /* MATHEMATICAL SANS-SERIF CAPITAL L */
+  {0x1d5ac, 1, 912}, /* MATHEMATICAL SANS-SERIF CAPITAL M */
+  {0x1d5ad, 1, 54}, /* MATHEMATICAL SANS-SERIF CAPITAL N */
+  {0x1d5ae, 1, 56}, /* MATHEMATICAL SANS-SERIF CAPITAL O */
+  {0x1d5af, 1, 914}, /* MATHEMATICAL SANS-SERIF CAPITAL P */
+  {0x1d5b0, 1, 1942}, /* MATHEMATICAL SANS-SERIF CAPITAL Q */
+  {0x1d5b1, 1, 274}, /* MATHEMATICAL SANS-SERIF CAPITAL R */
+  {0x1d5b2, 1, 286}, /* MATHEMATICAL SANS-SERIF CAPITAL S */
+  {0x1d5b3, 1, 302}, /* MATHEMATICAL SANS-SERIF CAPITAL T */
+  {0x1d5b4, 1, 66}, /* MATHEMATICAL SANS-SERIF CAPITAL U */
+  {0x1d5b5, 1, 1183}, /* MATHEMATICAL SANS-SERIF CAPITAL V */
+  {0x1d5b6, 1, 334}, /* MATHEMATICAL SANS-SERIF CAPITAL W */
+  {0x1d5b7, 1, 1211}, /* MATHEMATICAL SANS-SERIF CAPITAL X */
+  {0x1d5b8, 1, 74}, /* MATHEMATICAL SANS-SERIF CAPITAL Y */
+  {0x1d5b9, 1, 344}, /* MATHEMATICAL SANS-SERIF CAPITAL Z */
+  {0x1d5ba, 1, 3}, /* MATHEMATICAL SANS-SERIF SMALL A */
+  {0x1d5bb, 1, 918}, /* MATHEMATICAL SANS-SERIF SMALL B */
+  {0x1d5bc, 1, 88}, /* MATHEMATICAL SANS-SERIF SMALL C */
+  {0x1d5bd, 1, 160}, /* MATHEMATICAL SANS-SERIF SMALL D */
+  {0x1d5be, 1, 90}, /* MATHEMATICAL SANS-SERIF SMALL E */
+  {0x1d5bf, 1, 997}, /* MATHEMATICAL SANS-SERIF SMALL F */
+  {0x1d5c0, 1, 184}, /* MATHEMATICAL SANS-SERIF SMALL G */
+  {0x1d5c1, 1, 200}, /* MATHEMATICAL SANS-SERIF SMALL H */
+  {0x1d5c2, 1, 98}, /* MATHEMATICAL SANS-SERIF SMALL I */
+  {0x1d5c3, 1, 223}, /* MATHEMATICAL SANS-SERIF SMALL J */
+  {0x1d5c4, 1, 230}, /* MATHEMATICAL SANS-SERIF SMALL K */
+  {0x1d5c5, 1, 234}, /* MATHEMATICAL SANS-SERIF SMALL L */
+  {0x1d5c6, 1, 922}, /* MATHEMATICAL SANS-SERIF SMALL M */
+  {0x1d5c7, 1, 106}, /* MATHEMATICAL SANS-SERIF SMALL N */
+  {0x1d5c8, 1, 14}, /* MATHEMATICAL SANS-SERIF SMALL O */
+  {0x1d5c9, 1, 927}, /* MATHEMATICAL SANS-SERIF SMALL P */
+  {0x1d5ca, 1, 2335}, /* MATHEMATICAL SANS-SERIF SMALL Q */
+  {0x1d5cb, 1, 276}, /* MATHEMATICAL SANS-SERIF SMALL R */
+  {0x1d5cc, 1, 288}, /* MATHEMATICAL SANS-SERIF SMALL S */
+  {0x1d5cd, 1, 304}, /* MATHEMATICAL SANS-SERIF SMALL T */
+  {0x1d5ce, 1, 118}, /* MATHEMATICAL SANS-SERIF SMALL U */
+  {0x1d5cf, 1, 930}, /* MATHEMATICAL SANS-SERIF SMALL V */
+  {0x1d5d0, 1, 336}, /* MATHEMATICAL SANS-SERIF SMALL W */
+  {0x1d5d1, 1, 579}, /* MATHEMATICAL SANS-SERIF SMALL X */
+  {0x1d5d2, 1, 126}, /* MATHEMATICAL SANS-SERIF SMALL Y */
+  {0x1d5d3, 1, 346}, /* MATHEMATICAL SANS-SERIF SMALL Z */
+  {0x1d5d4, 1, 24}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL A */
+  {0x1d5d5, 1, 910}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL B */
+  {0x1d5d6, 1, 36}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL C */
+  {0x1d5d7, 1, 158}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL D */
+  {0x1d5d8, 1, 38}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL E */
+  {0x1d5d9, 1, 995}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL F */
+  {0x1d5da, 1, 182}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL G */
+  {0x1d5db, 1, 198}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL H */
+  {0x1d5dc, 1, 46}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL I */
+  {0x1d5dd, 1, 221}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL J */
+  {0x1d5de, 1, 228}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL K */
+  {0x1d5df, 1, 232}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL L */
+  {0x1d5e0, 1, 912}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL M */
+  {0x1d5e1, 1, 54}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL N */
+  {0x1d5e2, 1, 56}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL O */
+  {0x1d5e3, 1, 914}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL P */
+  {0x1d5e4, 1, 1942}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Q */
+  {0x1d5e5, 1, 274}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL R */
+  {0x1d5e6, 1, 286}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL S */
+  {0x1d5e7, 1, 302}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL T */
+  {0x1d5e8, 1, 66}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL U */
+  {0x1d5e9, 1, 1183}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL V */
+  {0x1d5ea, 1, 334}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL W */
+  {0x1d5eb, 1, 1211}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL X */
+  {0x1d5ec, 1, 74}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Y */
+  {0x1d5ed, 1, 344}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL Z */
+  {0x1d5ee, 1, 3}, /* MATHEMATICAL SANS-SERIF BOLD SMALL A */
+  {0x1d5ef, 1, 918}, /* MATHEMATICAL SANS-SERIF BOLD SMALL B */
+  {0x1d5f0, 1, 88}, /* MATHEMATICAL SANS-SERIF BOLD SMALL C */
+  {0x1d5f1, 1, 160}, /* MATHEMATICAL SANS-SERIF BOLD SMALL D */
+  {0x1d5f2, 1, 90}, /* MATHEMATICAL SANS-SERIF BOLD SMALL E */
+  {0x1d5f3, 1, 997}, /* MATHEMATICAL SANS-SERIF BOLD SMALL F */
+  {0x1d5f4, 1, 184}, /* MATHEMATICAL SANS-SERIF BOLD SMALL G */
+  {0x1d5f5, 1, 200}, /* MATHEMATICAL SANS-SERIF BOLD SMALL H */
+  {0x1d5f6, 1, 98}, /* MATHEMATICAL SANS-SERIF BOLD SMALL I */
+  {0x1d5f7, 1, 223}, /* MATHEMATICAL SANS-SERIF BOLD SMALL J */
+  {0x1d5f8, 1, 230}, /* MATHEMATICAL SANS-SERIF BOLD SMALL K */
+  {0x1d5f9, 1, 234}, /* MATHEMATICAL SANS-SERIF BOLD SMALL L */
+  {0x1d5fa, 1, 922}, /* MATHEMATICAL SANS-SERIF BOLD SMALL M */
+  {0x1d5fb, 1, 106}, /* MATHEMATICAL SANS-SERIF BOLD SMALL N */
+  {0x1d5fc, 1, 14}, /* MATHEMATICAL SANS-SERIF BOLD SMALL O */
+  {0x1d5fd, 1, 927}, /* MATHEMATICAL SANS-SERIF BOLD SMALL P */
+  {0x1d5fe, 1, 2335}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Q */
+  {0x1d5ff, 1, 276}, /* MATHEMATICAL SANS-SERIF BOLD SMALL R */
+  {0x1d600, 1, 288}, /* MATHEMATICAL SANS-SERIF BOLD SMALL S */
+  {0x1d601, 1, 304}, /* MATHEMATICAL SANS-SERIF BOLD SMALL T */
+  {0x1d602, 1, 118}, /* MATHEMATICAL SANS-SERIF BOLD SMALL U */
+  {0x1d603, 1, 930}, /* MATHEMATICAL SANS-SERIF BOLD SMALL V */
+  {0x1d604, 1, 336}, /* MATHEMATICAL SANS-SERIF BOLD SMALL W */
+  {0x1d605, 1, 579}, /* MATHEMATICAL SANS-SERIF BOLD SMALL X */
+  {0x1d606, 1, 126}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Y */
+  {0x1d607, 1, 346}, /* MATHEMATICAL SANS-SERIF BOLD SMALL Z */
+  {0x1d608, 1, 24}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL A */
+  {0x1d609, 1, 910}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL B */
+  {0x1d60a, 1, 36}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL C */
+  {0x1d60b, 1, 158}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL D */
+  {0x1d60c, 1, 38}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL E */
+  {0x1d60d, 1, 995}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL F */
+  {0x1d60e, 1, 182}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL G */
+  {0x1d60f, 1, 198}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL H */
+  {0x1d610, 1, 46}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL I */
+  {0x1d611, 1, 221}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL J */
+  {0x1d612, 1, 228}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL K */
+  {0x1d613, 1, 232}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL L */
+  {0x1d614, 1, 912}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL M */
+  {0x1d615, 1, 54}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL N */
+  {0x1d616, 1, 56}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL O */
+  {0x1d617, 1, 914}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL P */
+  {0x1d618, 1, 1942}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q */
+  {0x1d619, 1, 274}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL R */
+  {0x1d61a, 1, 286}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL S */
+  {0x1d61b, 1, 302}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL T */
+  {0x1d61c, 1, 66}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL U */
+  {0x1d61d, 1, 1183}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL V */
+  {0x1d61e, 1, 334}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL W */
+  {0x1d61f, 1, 1211}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL X */
+  {0x1d620, 1, 74}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y */
+  {0x1d621, 1, 344}, /* MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z */
+  {0x1d622, 1, 3}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL A */
+  {0x1d623, 1, 918}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL B */
+  {0x1d624, 1, 88}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL C */
+  {0x1d625, 1, 160}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL D */
+  {0x1d626, 1, 90}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL E */
+  {0x1d627, 1, 997}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL F */
+  {0x1d628, 1, 184}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL G */
+  {0x1d629, 1, 200}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL H */
+  {0x1d62a, 1, 98}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL I */
+  {0x1d62b, 1, 223}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL J */
+  {0x1d62c, 1, 230}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL K */
+  {0x1d62d, 1, 234}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL L */
+  {0x1d62e, 1, 922}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL M */
+  {0x1d62f, 1, 106}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL N */
+  {0x1d630, 1, 14}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL O */
+  {0x1d631, 1, 927}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL P */
+  {0x1d632, 1, 2335}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Q */
+  {0x1d633, 1, 276}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL R */
+  {0x1d634, 1, 288}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL S */
+  {0x1d635, 1, 304}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL T */
+  {0x1d636, 1, 118}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL U */
+  {0x1d637, 1, 930}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL V */
+  {0x1d638, 1, 336}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL W */
+  {0x1d639, 1, 579}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL X */
+  {0x1d63a, 1, 126}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Y */
+  {0x1d63b, 1, 346}, /* MATHEMATICAL SANS-SERIF ITALIC SMALL Z */
+  {0x1d63c, 1, 24}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A */
+  {0x1d63d, 1, 910}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B */
+  {0x1d63e, 1, 36}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C */
+  {0x1d63f, 1, 158}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D */
+  {0x1d640, 1, 38}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E */
+  {0x1d641, 1, 995}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F */
+  {0x1d642, 1, 182}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G */
+  {0x1d643, 1, 198}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H */
+  {0x1d644, 1, 46}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I */
+  {0x1d645, 1, 221}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J */
+  {0x1d646, 1, 228}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K */
+  {0x1d647, 1, 232}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L */
+  {0x1d648, 1, 912}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M */
+  {0x1d649, 1, 54}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N */
+  {0x1d64a, 1, 56}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O */
+  {0x1d64b, 1, 914}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P */
+  {0x1d64c, 1, 1942}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q */
+  {0x1d64d, 1, 274}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R */
+  {0x1d64e, 1, 286}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S */
+  {0x1d64f, 1, 302}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T */
+  {0x1d650, 1, 66}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U */
+  {0x1d651, 1, 1183}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V */
+  {0x1d652, 1, 334}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W */
+  {0x1d653, 1, 1211}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X */
+  {0x1d654, 1, 74}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y */
+  {0x1d655, 1, 344}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z */
+  {0x1d656, 1, 3}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A */
+  {0x1d657, 1, 918}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B */
+  {0x1d658, 1, 88}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C */
+  {0x1d659, 1, 160}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D */
+  {0x1d65a, 1, 90}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E */
+  {0x1d65b, 1, 997}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F */
+  {0x1d65c, 1, 184}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G */
+  {0x1d65d, 1, 200}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H */
+  {0x1d65e, 1, 98}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I */
+  {0x1d65f, 1, 223}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J */
+  {0x1d660, 1, 230}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K */
+  {0x1d661, 1, 234}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L */
+  {0x1d662, 1, 922}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M */
+  {0x1d663, 1, 106}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N */
+  {0x1d664, 1, 14}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O */
+  {0x1d665, 1, 927}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P */
+  {0x1d666, 1, 2335}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q */
+  {0x1d667, 1, 276}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R */
+  {0x1d668, 1, 288}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S */
+  {0x1d669, 1, 304}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T */
+  {0x1d66a, 1, 118}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U */
+  {0x1d66b, 1, 930}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V */
+  {0x1d66c, 1, 336}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W */
+  {0x1d66d, 1, 579}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X */
+  {0x1d66e, 1, 126}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y */
+  {0x1d66f, 1, 346}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z */
+  {0x1d670, 1, 24}, /* MATHEMATICAL MONOSPACE CAPITAL A */
+  {0x1d671, 1, 910}, /* MATHEMATICAL MONOSPACE CAPITAL B */
+  {0x1d672, 1, 36}, /* MATHEMATICAL MONOSPACE CAPITAL C */
+  {0x1d673, 1, 158}, /* MATHEMATICAL MONOSPACE CAPITAL D */
+  {0x1d674, 1, 38}, /* MATHEMATICAL MONOSPACE CAPITAL E */
+  {0x1d675, 1, 995}, /* MATHEMATICAL MONOSPACE CAPITAL F */
+  {0x1d676, 1, 182}, /* MATHEMATICAL MONOSPACE CAPITAL G */
+  {0x1d677, 1, 198}, /* MATHEMATICAL MONOSPACE CAPITAL H */
+  {0x1d678, 1, 46}, /* MATHEMATICAL MONOSPACE CAPITAL I */
+  {0x1d679, 1, 221}, /* MATHEMATICAL MONOSPACE CAPITAL J */
+  {0x1d67a, 1, 228}, /* MATHEMATICAL MONOSPACE CAPITAL K */
+  {0x1d67b, 1, 232}, /* MATHEMATICAL MONOSPACE CAPITAL L */
+  {0x1d67c, 1, 912}, /* MATHEMATICAL MONOSPACE CAPITAL M */
+  {0x1d67d, 1, 54}, /* MATHEMATICAL MONOSPACE CAPITAL N */
+  {0x1d67e, 1, 56}, /* MATHEMATICAL MONOSPACE CAPITAL O */
+  {0x1d67f, 1, 914}, /* MATHEMATICAL MONOSPACE CAPITAL P */
+  {0x1d680, 1, 1942}, /* MATHEMATICAL MONOSPACE CAPITAL Q */
+  {0x1d681, 1, 274}, /* MATHEMATICAL MONOSPACE CAPITAL R */
+  {0x1d682, 1, 286}, /* MATHEMATICAL MONOSPACE CAPITAL S */
+  {0x1d683, 1, 302}, /* MATHEMATICAL MONOSPACE CAPITAL T */
+  {0x1d684, 1, 66}, /* MATHEMATICAL MONOSPACE CAPITAL U */
+  {0x1d685, 1, 1183}, /* MATHEMATICAL MONOSPACE CAPITAL V */
+  {0x1d686, 1, 334}, /* MATHEMATICAL MONOSPACE CAPITAL W */
+  {0x1d687, 1, 1211}, /* MATHEMATICAL MONOSPACE CAPITAL X */
+  {0x1d688, 1, 74}, /* MATHEMATICAL MONOSPACE CAPITAL Y */
+  {0x1d689, 1, 344}, /* MATHEMATICAL MONOSPACE CAPITAL Z */
+  {0x1d68a, 1, 3}, /* MATHEMATICAL MONOSPACE SMALL A */
+  {0x1d68b, 1, 918}, /* MATHEMATICAL MONOSPACE SMALL B */
+  {0x1d68c, 1, 88}, /* MATHEMATICAL MONOSPACE SMALL C */
+  {0x1d68d, 1, 160}, /* MATHEMATICAL MONOSPACE SMALL D */
+  {0x1d68e, 1, 90}, /* MATHEMATICAL MONOSPACE SMALL E */
+  {0x1d68f, 1, 997}, /* MATHEMATICAL MONOSPACE SMALL F */
+  {0x1d690, 1, 184}, /* MATHEMATICAL MONOSPACE SMALL G */
+  {0x1d691, 1, 200}, /* MATHEMATICAL MONOSPACE SMALL H */
+  {0x1d692, 1, 98}, /* MATHEMATICAL MONOSPACE SMALL I */
+  {0x1d693, 1, 223}, /* MATHEMATICAL MONOSPACE SMALL J */
+  {0x1d694, 1, 230}, /* MATHEMATICAL MONOSPACE SMALL K */
+  {0x1d695, 1, 234}, /* MATHEMATICAL MONOSPACE SMALL L */
+  {0x1d696, 1, 922}, /* MATHEMATICAL MONOSPACE SMALL M */
+  {0x1d697, 1, 106}, /* MATHEMATICAL MONOSPACE SMALL N */
+  {0x1d698, 1, 14}, /* MATHEMATICAL MONOSPACE SMALL O */
+  {0x1d699, 1, 927}, /* MATHEMATICAL MONOSPACE SMALL P */
+  {0x1d69a, 1, 2335}, /* MATHEMATICAL MONOSPACE SMALL Q */
+  {0x1d69b, 1, 276}, /* MATHEMATICAL MONOSPACE SMALL R */
+  {0x1d69c, 1, 288}, /* MATHEMATICAL MONOSPACE SMALL S */
+  {0x1d69d, 1, 304}, /* MATHEMATICAL MONOSPACE SMALL T */
+  {0x1d69e, 1, 118}, /* MATHEMATICAL MONOSPACE SMALL U */
+  {0x1d69f, 1, 930}, /* MATHEMATICAL MONOSPACE SMALL V */
+  {0x1d6a0, 1, 336}, /* MATHEMATICAL MONOSPACE SMALL W */
+  {0x1d6a1, 1, 579}, /* MATHEMATICAL MONOSPACE SMALL X */
+  {0x1d6a2, 1, 126}, /* MATHEMATICAL MONOSPACE SMALL Y */
+  {0x1d6a3, 1, 346}, /* MATHEMATICAL MONOSPACE SMALL Z */
+  {0x1d6a8, 1, 590}, /* MATHEMATICAL BOLD CAPITAL ALPHA */
+  {0x1d6a9, 1, 5148}, /* MATHEMATICAL BOLD CAPITAL BETA */
+  {0x1d6aa, 1, 1957}, /* MATHEMATICAL BOLD CAPITAL GAMMA */
+  {0x1d6ab, 1, 5149}, /* MATHEMATICAL BOLD CAPITAL DELTA */
+  {0x1d6ac, 1, 592}, /* MATHEMATICAL BOLD CAPITAL EPSILON */
+  {0x1d6ad, 1, 5150}, /* MATHEMATICAL BOLD CAPITAL ZETA */
+  {0x1d6ae, 1, 594}, /* MATHEMATICAL BOLD CAPITAL ETA */
+  {0x1d6af, 1, 641}, /* MATHEMATICAL BOLD CAPITAL THETA */
+  {0x1d6b0, 1, 596}, /* MATHEMATICAL BOLD CAPITAL IOTA */
+  {0x1d6b1, 1, 5151}, /* MATHEMATICAL BOLD CAPITAL KAPPA */
+  {0x1d6b2, 1, 5152}, /* MATHEMATICAL BOLD CAPITAL LAMDA */
+  {0x1d6b3, 1, 5153}, /* MATHEMATICAL BOLD CAPITAL MU */
+  {0x1d6b4, 1, 5154}, /* MATHEMATICAL BOLD CAPITAL NU */
+  {0x1d6b5, 1, 5155}, /* MATHEMATICAL BOLD CAPITAL XI */
+  {0x1d6b6, 1, 598}, /* MATHEMATICAL BOLD CAPITAL OMICRON */
+  {0x1d6b7, 1, 1958}, /* MATHEMATICAL BOLD CAPITAL PI */
+  {0x1d6b8, 1, 1843}, /* MATHEMATICAL BOLD CAPITAL RHO */
+  {0x1d6b9, 1, 5156}, /* MATHEMATICAL BOLD CAPITAL THETA SYMBOL */
+  {0x1d6ba, 1, 642}, /* MATHEMATICAL BOLD CAPITAL SIGMA */
+  {0x1d6bb, 1, 5157}, /* MATHEMATICAL BOLD CAPITAL TAU */
+  {0x1d6bc, 1, 600}, /* MATHEMATICAL BOLD CAPITAL UPSILON */
+  {0x1d6bd, 1, 5158}, /* MATHEMATICAL BOLD CAPITAL PHI */
+  {0x1d6be, 1, 5159}, /* MATHEMATICAL BOLD CAPITAL CHI */
+  {0x1d6bf, 1, 5160}, /* MATHEMATICAL BOLD CAPITAL PSI */
+  {0x1d6c0, 1, 602}, /* MATHEMATICAL BOLD CAPITAL OMEGA */
+  {0x1d6c1, 1, 5161}, /* MATHEMATICAL BOLD NABLA */
+  {0x1d6c2, 1, 610}, /* MATHEMATICAL BOLD SMALL ALPHA */
+  {0x1d6c3, 1, 630}, /* MATHEMATICAL BOLD SMALL BETA */
+  {0x1d6c4, 1, 932}, /* MATHEMATICAL BOLD SMALL GAMMA */
+  {0x1d6c5, 1, 933}, /* MATHEMATICAL BOLD SMALL DELTA */
+  {0x1d6c6, 1, 612}, /* MATHEMATICAL BOLD SMALL EPSILON */
+  {0x1d6c7, 1, 5162}, /* MATHEMATICAL BOLD SMALL ZETA */
+  {0x1d6c8, 1, 614}, /* MATHEMATICAL BOLD SMALL ETA */
+  {0x1d6c9, 1, 631}, /* MATHEMATICAL BOLD SMALL THETA */
+  {0x1d6ca, 1, 616}, /* MATHEMATICAL BOLD SMALL IOTA */
+  {0x1d6cb, 1, 638}, /* MATHEMATICAL BOLD SMALL KAPPA */
+  {0x1d6cc, 1, 5163}, /* MATHEMATICAL BOLD SMALL LAMDA */
+  {0x1d6cd, 1, 10}, /* MATHEMATICAL BOLD SMALL MU */
+  {0x1d6ce, 1, 5164}, /* MATHEMATICAL BOLD SMALL NU */
+  {0x1d6cf, 1, 5165}, /* MATHEMATICAL BOLD SMALL XI */
+  {0x1d6d0, 1, 624}, /* MATHEMATICAL BOLD SMALL OMICRON */
+  {0x1d6d1, 1, 637}, /* MATHEMATICAL BOLD SMALL PI */
+  {0x1d6d2, 1, 639}, /* MATHEMATICAL BOLD SMALL RHO */
+  {0x1d6d3, 1, 640}, /* MATHEMATICAL BOLD SMALL FINAL SIGMA */
+  {0x1d6d4, 1, 5166}, /* MATHEMATICAL BOLD SMALL SIGMA */
+  {0x1d6d5, 1, 5167}, /* MATHEMATICAL BOLD SMALL TAU */
+  {0x1d6d6, 1, 622}, /* MATHEMATICAL BOLD SMALL UPSILON */
+  {0x1d6d7, 1, 636}, /* MATHEMATICAL BOLD SMALL PHI */
+  {0x1d6d8, 1, 934}, /* MATHEMATICAL BOLD SMALL CHI */
+  {0x1d6d9, 1, 5168}, /* MATHEMATICAL BOLD SMALL PSI */
+  {0x1d6da, 1, 628}, /* MATHEMATICAL BOLD SMALL OMEGA */
+  {0x1d6db, 1, 5169}, /* MATHEMATICAL BOLD PARTIAL DIFFERENTIAL */
+  {0x1d6dc, 1, 5170}, /* MATHEMATICAL BOLD EPSILON SYMBOL */
+  {0x1d6dd, 1, 5171}, /* MATHEMATICAL BOLD THETA SYMBOL */
+  {0x1d6de, 1, 5172}, /* MATHEMATICAL BOLD KAPPA SYMBOL */
+  {0x1d6df, 1, 5173}, /* MATHEMATICAL BOLD PHI SYMBOL */
+  {0x1d6e0, 1, 5174}, /* MATHEMATICAL BOLD RHO SYMBOL */
+  {0x1d6e1, 1, 5175}, /* MATHEMATICAL BOLD PI SYMBOL */
+  {0x1d6e2, 1, 590}, /* MATHEMATICAL ITALIC CAPITAL ALPHA */
+  {0x1d6e3, 1, 5148}, /* MATHEMATICAL ITALIC CAPITAL BETA */
+  {0x1d6e4, 1, 1957}, /* MATHEMATICAL ITALIC CAPITAL GAMMA */
+  {0x1d6e5, 1, 5149}, /* MATHEMATICAL ITALIC CAPITAL DELTA */
+  {0x1d6e6, 1, 592}, /* MATHEMATICAL ITALIC CAPITAL EPSILON */
+  {0x1d6e7, 1, 5150}, /* MATHEMATICAL ITALIC CAPITAL ZETA */
+  {0x1d6e8, 1, 594}, /* MATHEMATICAL ITALIC CAPITAL ETA */
+  {0x1d6e9, 1, 641}, /* MATHEMATICAL ITALIC CAPITAL THETA */
+  {0x1d6ea, 1, 596}, /* MATHEMATICAL ITALIC CAPITAL IOTA */
+  {0x1d6eb, 1, 5151}, /* MATHEMATICAL ITALIC CAPITAL KAPPA */
+  {0x1d6ec, 1, 5152}, /* MATHEMATICAL ITALIC CAPITAL LAMDA */
+  {0x1d6ed, 1, 5153}, /* MATHEMATICAL ITALIC CAPITAL MU */
+  {0x1d6ee, 1, 5154}, /* MATHEMATICAL ITALIC CAPITAL NU */
+  {0x1d6ef, 1, 5155}, /* MATHEMATICAL ITALIC CAPITAL XI */
+  {0x1d6f0, 1, 598}, /* MATHEMATICAL ITALIC CAPITAL OMICRON */
+  {0x1d6f1, 1, 1958}, /* MATHEMATICAL ITALIC CAPITAL PI */
+  {0x1d6f2, 1, 1843}, /* MATHEMATICAL ITALIC CAPITAL RHO */
+  {0x1d6f3, 1, 5156}, /* MATHEMATICAL ITALIC CAPITAL THETA SYMBOL */
+  {0x1d6f4, 1, 642}, /* MATHEMATICAL ITALIC CAPITAL SIGMA */
+  {0x1d6f5, 1, 5157}, /* MATHEMATICAL ITALIC CAPITAL TAU */
+  {0x1d6f6, 1, 600}, /* MATHEMATICAL ITALIC CAPITAL UPSILON */
+  {0x1d6f7, 1, 5158}, /* MATHEMATICAL ITALIC CAPITAL PHI */
+  {0x1d6f8, 1, 5159}, /* MATHEMATICAL ITALIC CAPITAL CHI */
+  {0x1d6f9, 1, 5160}, /* MATHEMATICAL ITALIC CAPITAL PSI */
+  {0x1d6fa, 1, 602}, /* MATHEMATICAL ITALIC CAPITAL OMEGA */
+  {0x1d6fb, 1, 5161}, /* MATHEMATICAL ITALIC NABLA */
+  {0x1d6fc, 1, 610}, /* MATHEMATICAL ITALIC SMALL ALPHA */
+  {0x1d6fd, 1, 630}, /* MATHEMATICAL ITALIC SMALL BETA */
+  {0x1d6fe, 1, 932}, /* MATHEMATICAL ITALIC SMALL GAMMA */
+  {0x1d6ff, 1, 933}, /* MATHEMATICAL ITALIC SMALL DELTA */
+  {0x1d700, 1, 612}, /* MATHEMATICAL ITALIC SMALL EPSILON */
+  {0x1d701, 1, 5162}, /* MATHEMATICAL ITALIC SMALL ZETA */
+  {0x1d702, 1, 614}, /* MATHEMATICAL ITALIC SMALL ETA */
+  {0x1d703, 1, 631}, /* MATHEMATICAL ITALIC SMALL THETA */
+  {0x1d704, 1, 616}, /* MATHEMATICAL ITALIC SMALL IOTA */
+  {0x1d705, 1, 638}, /* MATHEMATICAL ITALIC SMALL KAPPA */
+  {0x1d706, 1, 5163}, /* MATHEMATICAL ITALIC SMALL LAMDA */
+  {0x1d707, 1, 10}, /* MATHEMATICAL ITALIC SMALL MU */
+  {0x1d708, 1, 5164}, /* MATHEMATICAL ITALIC SMALL NU */
+  {0x1d709, 1, 5165}, /* MATHEMATICAL ITALIC SMALL XI */
+  {0x1d70a, 1, 624}, /* MATHEMATICAL ITALIC SMALL OMICRON */
+  {0x1d70b, 1, 637}, /* MATHEMATICAL ITALIC SMALL PI */
+  {0x1d70c, 1, 639}, /* MATHEMATICAL ITALIC SMALL RHO */
+  {0x1d70d, 1, 640}, /* MATHEMATICAL ITALIC SMALL FINAL SIGMA */
+  {0x1d70e, 1, 5166}, /* MATHEMATICAL ITALIC SMALL SIGMA */
+  {0x1d70f, 1, 5167}, /* MATHEMATICAL ITALIC SMALL TAU */
+  {0x1d710, 1, 622}, /* MATHEMATICAL ITALIC SMALL UPSILON */
+  {0x1d711, 1, 636}, /* MATHEMATICAL ITALIC SMALL PHI */
+  {0x1d712, 1, 934}, /* MATHEMATICAL ITALIC SMALL CHI */
+  {0x1d713, 1, 5168}, /* MATHEMATICAL ITALIC SMALL PSI */
+  {0x1d714, 1, 628}, /* MATHEMATICAL ITALIC SMALL OMEGA */
+  {0x1d715, 1, 5169}, /* MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL */
+  {0x1d716, 1, 5170}, /* MATHEMATICAL ITALIC EPSILON SYMBOL */
+  {0x1d717, 1, 5171}, /* MATHEMATICAL ITALIC THETA SYMBOL */
+  {0x1d718, 1, 5172}, /* MATHEMATICAL ITALIC KAPPA SYMBOL */
+  {0x1d719, 1, 5173}, /* MATHEMATICAL ITALIC PHI SYMBOL */
+  {0x1d71a, 1, 5174}, /* MATHEMATICAL ITALIC RHO SYMBOL */
+  {0x1d71b, 1, 5175}, /* MATHEMATICAL ITALIC PI SYMBOL */
+  {0x1d71c, 1, 590}, /* MATHEMATICAL BOLD ITALIC CAPITAL ALPHA */
+  {0x1d71d, 1, 5148}, /* MATHEMATICAL BOLD ITALIC CAPITAL BETA */
+  {0x1d71e, 1, 1957}, /* MATHEMATICAL BOLD ITALIC CAPITAL GAMMA */
+  {0x1d71f, 1, 5149}, /* MATHEMATICAL BOLD ITALIC CAPITAL DELTA */
+  {0x1d720, 1, 592}, /* MATHEMATICAL BOLD ITALIC CAPITAL EPSILON */
+  {0x1d721, 1, 5150}, /* MATHEMATICAL BOLD ITALIC CAPITAL ZETA */
+  {0x1d722, 1, 594}, /* MATHEMATICAL BOLD ITALIC CAPITAL ETA */
+  {0x1d723, 1, 641}, /* MATHEMATICAL BOLD ITALIC CAPITAL THETA */
+  {0x1d724, 1, 596}, /* MATHEMATICAL BOLD ITALIC CAPITAL IOTA */
+  {0x1d725, 1, 5151}, /* MATHEMATICAL BOLD ITALIC CAPITAL KAPPA */
+  {0x1d726, 1, 5152}, /* MATHEMATICAL BOLD ITALIC CAPITAL LAMDA */
+  {0x1d727, 1, 5153}, /* MATHEMATICAL BOLD ITALIC CAPITAL MU */
+  {0x1d728, 1, 5154}, /* MATHEMATICAL BOLD ITALIC CAPITAL NU */
+  {0x1d729, 1, 5155}, /* MATHEMATICAL BOLD ITALIC CAPITAL XI */
+  {0x1d72a, 1, 598}, /* MATHEMATICAL BOLD ITALIC CAPITAL OMICRON */
+  {0x1d72b, 1, 1958}, /* MATHEMATICAL BOLD ITALIC CAPITAL PI */
+  {0x1d72c, 1, 1843}, /* MATHEMATICAL BOLD ITALIC CAPITAL RHO */
+  {0x1d72d, 1, 5156}, /* MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL */
+  {0x1d72e, 1, 642}, /* MATHEMATICAL BOLD ITALIC CAPITAL SIGMA */
+  {0x1d72f, 1, 5157}, /* MATHEMATICAL BOLD ITALIC CAPITAL TAU */
+  {0x1d730, 1, 600}, /* MATHEMATICAL BOLD ITALIC CAPITAL UPSILON */
+  {0x1d731, 1, 5158}, /* MATHEMATICAL BOLD ITALIC CAPITAL PHI */
+  {0x1d732, 1, 5159}, /* MATHEMATICAL BOLD ITALIC CAPITAL CHI */
+  {0x1d733, 1, 5160}, /* MATHEMATICAL BOLD ITALIC CAPITAL PSI */
+  {0x1d734, 1, 602}, /* MATHEMATICAL BOLD ITALIC CAPITAL OMEGA */
+  {0x1d735, 1, 5161}, /* MATHEMATICAL BOLD ITALIC NABLA */
+  {0x1d736, 1, 610}, /* MATHEMATICAL BOLD ITALIC SMALL ALPHA */
+  {0x1d737, 1, 630}, /* MATHEMATICAL BOLD ITALIC SMALL BETA */
+  {0x1d738, 1, 932}, /* MATHEMATICAL BOLD ITALIC SMALL GAMMA */
+  {0x1d739, 1, 933}, /* MATHEMATICAL BOLD ITALIC SMALL DELTA */
+  {0x1d73a, 1, 612}, /* MATHEMATICAL BOLD ITALIC SMALL EPSILON */
+  {0x1d73b, 1, 5162}, /* MATHEMATICAL BOLD ITALIC SMALL ZETA */
+  {0x1d73c, 1, 614}, /* MATHEMATICAL BOLD ITALIC SMALL ETA */
+  {0x1d73d, 1, 631}, /* MATHEMATICAL BOLD ITALIC SMALL THETA */
+  {0x1d73e, 1, 616}, /* MATHEMATICAL BOLD ITALIC SMALL IOTA */
+  {0x1d73f, 1, 638}, /* MATHEMATICAL BOLD ITALIC SMALL KAPPA */
+  {0x1d740, 1, 5163}, /* MATHEMATICAL BOLD ITALIC SMALL LAMDA */
+  {0x1d741, 1, 10}, /* MATHEMATICAL BOLD ITALIC SMALL MU */
+  {0x1d742, 1, 5164}, /* MATHEMATICAL BOLD ITALIC SMALL NU */
+  {0x1d743, 1, 5165}, /* MATHEMATICAL BOLD ITALIC SMALL XI */
+  {0x1d744, 1, 624}, /* MATHEMATICAL BOLD ITALIC SMALL OMICRON */
+  {0x1d745, 1, 637}, /* MATHEMATICAL BOLD ITALIC SMALL PI */
+  {0x1d746, 1, 639}, /* MATHEMATICAL BOLD ITALIC SMALL RHO */
+  {0x1d747, 1, 640}, /* MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA */
+  {0x1d748, 1, 5166}, /* MATHEMATICAL BOLD ITALIC SMALL SIGMA */
+  {0x1d749, 1, 5167}, /* MATHEMATICAL BOLD ITALIC SMALL TAU */
+  {0x1d74a, 1, 622}, /* MATHEMATICAL BOLD ITALIC SMALL UPSILON */
+  {0x1d74b, 1, 636}, /* MATHEMATICAL BOLD ITALIC SMALL PHI */
+  {0x1d74c, 1, 934}, /* MATHEMATICAL BOLD ITALIC SMALL CHI */
+  {0x1d74d, 1, 5168}, /* MATHEMATICAL BOLD ITALIC SMALL PSI */
+  {0x1d74e, 1, 628}, /* MATHEMATICAL BOLD ITALIC SMALL OMEGA */
+  {0x1d74f, 1, 5169}, /* MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL */
+  {0x1d750, 1, 5170}, /* MATHEMATICAL BOLD ITALIC EPSILON SYMBOL */
+  {0x1d751, 1, 5171}, /* MATHEMATICAL BOLD ITALIC THETA SYMBOL */
+  {0x1d752, 1, 5172}, /* MATHEMATICAL BOLD ITALIC KAPPA SYMBOL */
+  {0x1d753, 1, 5173}, /* MATHEMATICAL BOLD ITALIC PHI SYMBOL */
+  {0x1d754, 1, 5174}, /* MATHEMATICAL BOLD ITALIC RHO SYMBOL */
+  {0x1d755, 1, 5175}, /* MATHEMATICAL BOLD ITALIC PI SYMBOL */
+  {0x1d756, 1, 590}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA */
+  {0x1d757, 1, 5148}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA */
+  {0x1d758, 1, 1957}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA */
+  {0x1d759, 1, 5149}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA */
+  {0x1d75a, 1, 592}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON */
+  {0x1d75b, 1, 5150}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA */
+  {0x1d75c, 1, 594}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA */
+  {0x1d75d, 1, 641}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA */
+  {0x1d75e, 1, 596}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA */
+  {0x1d75f, 1, 5151}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA */
+  {0x1d760, 1, 5152}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA */
+  {0x1d761, 1, 5153}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL MU */
+  {0x1d762, 1, 5154}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL NU */
+  {0x1d763, 1, 5155}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL XI */
+  {0x1d764, 1, 598}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON */
+  {0x1d765, 1, 1958}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PI */
+  {0x1d766, 1, 1843}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO */
+  {0x1d767, 1, 5156}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL */
+  {0x1d768, 1, 642}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA */
+  {0x1d769, 1, 5157}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU */
+  {0x1d76a, 1, 600}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON */
+  {0x1d76b, 1, 5158}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI */
+  {0x1d76c, 1, 5159}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI */
+  {0x1d76d, 1, 5160}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI */
+  {0x1d76e, 1, 602}, /* MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA */
+  {0x1d76f, 1, 5161}, /* MATHEMATICAL SANS-SERIF BOLD NABLA */
+  {0x1d770, 1, 610}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA */
+  {0x1d771, 1, 630}, /* MATHEMATICAL SANS-SERIF BOLD SMALL BETA */
+  {0x1d772, 1, 932}, /* MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA */
+  {0x1d773, 1, 933}, /* MATHEMATICAL SANS-SERIF BOLD SMALL DELTA */
+  {0x1d774, 1, 612}, /* MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON */
+  {0x1d775, 1, 5162}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ZETA */
+  {0x1d776, 1, 614}, /* MATHEMATICAL SANS-SERIF BOLD SMALL ETA */
+  {0x1d777, 1, 631}, /* MATHEMATICAL SANS-SERIF BOLD SMALL THETA */
+  {0x1d778, 1, 616}, /* MATHEMATICAL SANS-SERIF BOLD SMALL IOTA */
+  {0x1d779, 1, 638}, /* MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA */
+  {0x1d77a, 1, 5163}, /* MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA */
+  {0x1d77b, 1, 10}, /* MATHEMATICAL SANS-SERIF BOLD SMALL MU */
+  {0x1d77c, 1, 5164}, /* MATHEMATICAL SANS-SERIF BOLD SMALL NU */
+  {0x1d77d, 1, 5165}, /* MATHEMATICAL SANS-SERIF BOLD SMALL XI */
+  {0x1d77e, 1, 624}, /* MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON */
+  {0x1d77f, 1, 637}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PI */
+  {0x1d780, 1, 639}, /* MATHEMATICAL SANS-SERIF BOLD SMALL RHO */
+  {0x1d781, 1, 640}, /* MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA */
+  {0x1d782, 1, 5166}, /* MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA */
+  {0x1d783, 1, 5167}, /* MATHEMATICAL SANS-SERIF BOLD SMALL TAU */
+  {0x1d784, 1, 622}, /* MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON */
+  {0x1d785, 1, 636}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PHI */
+  {0x1d786, 1, 934}, /* MATHEMATICAL SANS-SERIF BOLD SMALL CHI */
+  {0x1d787, 1, 5168}, /* MATHEMATICAL SANS-SERIF BOLD SMALL PSI */
+  {0x1d788, 1, 628}, /* MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA */
+  {0x1d789, 1, 5169}, /* MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL */
+  {0x1d78a, 1, 5170}, /* MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL */
+  {0x1d78b, 1, 5171}, /* MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL */
+  {0x1d78c, 1, 5172}, /* MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL */
+  {0x1d78d, 1, 5173}, /* MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL */
+  {0x1d78e, 1, 5174}, /* MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL */
+  {0x1d78f, 1, 5175}, /* MATHEMATICAL SANS-SERIF BOLD PI SYMBOL */
+  {0x1d790, 1, 590}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA */
+  {0x1d791, 1, 5148}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA */
+  {0x1d792, 1, 1957}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA */
+  {0x1d793, 1, 5149}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA */
+  {0x1d794, 1, 592}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON */
+  {0x1d795, 1, 5150}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA */
+  {0x1d796, 1, 594}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA */
+  {0x1d797, 1, 641}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA */
+  {0x1d798, 1, 596}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA */
+  {0x1d799, 1, 5151}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA */
+  {0x1d79a, 1, 5152}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA */
+  {0x1d79b, 1, 5153}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU */
+  {0x1d79c, 1, 5154}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU */
+  {0x1d79d, 1, 5155}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI */
+  {0x1d79e, 1, 598}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON */
+  {0x1d79f, 1, 1958}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI */
+  {0x1d7a0, 1, 1843}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO */
+  {0x1d7a1, 1, 5156}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL */
+  {0x1d7a2, 1, 642}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA */
+  {0x1d7a3, 1, 5157}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU */
+  {0x1d7a4, 1, 600}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON */
+  {0x1d7a5, 1, 5158}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI */
+  {0x1d7a6, 1, 5159}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI */
+  {0x1d7a7, 1, 5160}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI */
+  {0x1d7a8, 1, 602}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA */
+  {0x1d7a9, 1, 5161}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA */
+  {0x1d7aa, 1, 610}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA */
+  {0x1d7ab, 1, 630}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA */
+  {0x1d7ac, 1, 932}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA */
+  {0x1d7ad, 1, 933}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA */
+  {0x1d7ae, 1, 612}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON */
+  {0x1d7af, 1, 5162}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA */
+  {0x1d7b0, 1, 614}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA */
+  {0x1d7b1, 1, 631}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA */
+  {0x1d7b2, 1, 616}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA */
+  {0x1d7b3, 1, 638}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA */
+  {0x1d7b4, 1, 5163}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA */
+  {0x1d7b5, 1, 10}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU */
+  {0x1d7b6, 1, 5164}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU */
+  {0x1d7b7, 1, 5165}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI */
+  {0x1d7b8, 1, 624}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON */
+  {0x1d7b9, 1, 637}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI */
+  {0x1d7ba, 1, 639}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO */
+  {0x1d7bb, 1, 640}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA */
+  {0x1d7bc, 1, 5166}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA */
+  {0x1d7bd, 1, 5167}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU */
+  {0x1d7be, 1, 622}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON */
+  {0x1d7bf, 1, 636}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI */
+  {0x1d7c0, 1, 934}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI */
+  {0x1d7c1, 1, 5168}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI */
+  {0x1d7c2, 1, 628}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA */
+  {0x1d7c3, 1, 5169}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL */
+  {0x1d7c4, 1, 5170}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL */
+  {0x1d7c5, 1, 5171}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL */
+  {0x1d7c6, 1, 5172}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL */
+  {0x1d7c7, 1, 5173}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL */
+  {0x1d7c8, 1, 5174}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL */
+  {0x1d7c9, 1, 5175}, /* MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL */
+  {0x1d7ce, 1, 1909}, /* MATHEMATICAL BOLD DIGIT ZERO */
+  {0x1d7cf, 1, 13}, /* MATHEMATICAL BOLD DIGIT ONE */
+  {0x1d7d0, 1, 6}, /* MATHEMATICAL BOLD DIGIT TWO */
+  {0x1d7d1, 1, 7}, /* MATHEMATICAL BOLD DIGIT THREE */
+  {0x1d7d2, 1, 17}, /* MATHEMATICAL BOLD DIGIT FOUR */
+  {0x1d7d3, 1, 1910}, /* MATHEMATICAL BOLD DIGIT FIVE */
+  {0x1d7d4, 1, 1911}, /* MATHEMATICAL BOLD DIGIT SIX */
+  {0x1d7d5, 1, 1912}, /* MATHEMATICAL BOLD DIGIT SEVEN */
+  {0x1d7d6, 1, 1913}, /* MATHEMATICAL BOLD DIGIT EIGHT */
+  {0x1d7d7, 1, 1914}, /* MATHEMATICAL BOLD DIGIT NINE */
+  {0x1d7d8, 1, 1909}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO */
+  {0x1d7d9, 1, 13}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT ONE */
+  {0x1d7da, 1, 6}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT TWO */
+  {0x1d7db, 1, 7}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT THREE */
+  {0x1d7dc, 1, 17}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR */
+  {0x1d7dd, 1, 1910}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE */
+  {0x1d7de, 1, 1911}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SIX */
+  {0x1d7df, 1, 1912}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN */
+  {0x1d7e0, 1, 1913}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT */
+  {0x1d7e1, 1, 1914}, /* MATHEMATICAL DOUBLE-STRUCK DIGIT NINE */
+  {0x1d7e2, 1, 1909}, /* MATHEMATICAL SANS-SERIF DIGIT ZERO */
+  {0x1d7e3, 1, 13}, /* MATHEMATICAL SANS-SERIF DIGIT ONE */
+  {0x1d7e4, 1, 6}, /* MATHEMATICAL SANS-SERIF DIGIT TWO */
+  {0x1d7e5, 1, 7}, /* MATHEMATICAL SANS-SERIF DIGIT THREE */
+  {0x1d7e6, 1, 17}, /* MATHEMATICAL SANS-SERIF DIGIT FOUR */
+  {0x1d7e7, 1, 1910}, /* MATHEMATICAL SANS-SERIF DIGIT FIVE */
+  {0x1d7e8, 1, 1911}, /* MATHEMATICAL SANS-SERIF DIGIT SIX */
+  {0x1d7e9, 1, 1912}, /* MATHEMATICAL SANS-SERIF DIGIT SEVEN */
+  {0x1d7ea, 1, 1913}, /* MATHEMATICAL SANS-SERIF DIGIT EIGHT */
+  {0x1d7eb, 1, 1914}, /* MATHEMATICAL SANS-SERIF DIGIT NINE */
+  {0x1d7ec, 1, 1909}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO */
+  {0x1d7ed, 1, 13}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT ONE */
+  {0x1d7ee, 1, 6}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT TWO */
+  {0x1d7ef, 1, 7}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT THREE */
+  {0x1d7f0, 1, 17}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR */
+  {0x1d7f1, 1, 1910}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE */
+  {0x1d7f2, 1, 1911}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT SIX */
+  {0x1d7f3, 1, 1912}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN */
+  {0x1d7f4, 1, 1913}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT */
+  {0x1d7f5, 1, 1914}, /* MATHEMATICAL SANS-SERIF BOLD DIGIT NINE */
+  {0x1d7f6, 1, 1909}, /* MATHEMATICAL MONOSPACE DIGIT ZERO */
+  {0x1d7f7, 1, 13}, /* MATHEMATICAL MONOSPACE DIGIT ONE */
+  {0x1d7f8, 1, 6}, /* MATHEMATICAL MONOSPACE DIGIT TWO */
+  {0x1d7f9, 1, 7}, /* MATHEMATICAL MONOSPACE DIGIT THREE */
+  {0x1d7fa, 1, 17}, /* MATHEMATICAL MONOSPACE DIGIT FOUR */
+  {0x1d7fb, 1, 1910}, /* MATHEMATICAL MONOSPACE DIGIT FIVE */
+  {0x1d7fc, 1, 1911}, /* MATHEMATICAL MONOSPACE DIGIT SIX */
+  {0x1d7fd, 1, 1912}, /* MATHEMATICAL MONOSPACE DIGIT SEVEN */
+  {0x1d7fe, 1, 1913}, /* MATHEMATICAL MONOSPACE DIGIT EIGHT */
+  {0x1d7ff, 1, 1914}, /* MATHEMATICAL MONOSPACE DIGIT NINE */
+  {0x2f800, 1, 5176}, /* CJK COMPATIBILITY IDEOGRAPH-2F800 */
+  {0x2f801, 1, 5177}, /* CJK COMPATIBILITY IDEOGRAPH-2F801 */
+  {0x2f802, 1, 5178}, /* CJK COMPATIBILITY IDEOGRAPH-2F802 */
+  {0x2f803, 1, 5179}, /* CJK COMPATIBILITY IDEOGRAPH-2F803 */
+  {0x2f804, 1, 5180}, /* CJK COMPATIBILITY IDEOGRAPH-2F804 */
+  {0x2f805, 1, 4142}, /* CJK COMPATIBILITY IDEOGRAPH-2F805 */
+  {0x2f806, 1, 5181}, /* CJK COMPATIBILITY IDEOGRAPH-2F806 */
+  {0x2f807, 1, 5182}, /* CJK COMPATIBILITY IDEOGRAPH-2F807 */
+  {0x2f808, 1, 5183}, /* CJK COMPATIBILITY IDEOGRAPH-2F808 */
+  {0x2f809, 1, 5184}, /* CJK COMPATIBILITY IDEOGRAPH-2F809 */
+  {0x2f80a, 1, 4143}, /* CJK COMPATIBILITY IDEOGRAPH-2F80A */
+  {0x2f80b, 1, 5185}, /* CJK COMPATIBILITY IDEOGRAPH-2F80B */
+  {0x2f80c, 1, 5186}, /* CJK COMPATIBILITY IDEOGRAPH-2F80C */
+  {0x2f80d, 1, 5187}, /* CJK COMPATIBILITY IDEOGRAPH-2F80D */
+  {0x2f80e, 1, 4144}, /* CJK COMPATIBILITY IDEOGRAPH-2F80E */
+  {0x2f80f, 1, 5188}, /* CJK COMPATIBILITY IDEOGRAPH-2F80F */
+  {0x2f810, 1, 5189}, /* CJK COMPATIBILITY IDEOGRAPH-2F810 */
+  {0x2f811, 1, 5190}, /* CJK COMPATIBILITY IDEOGRAPH-2F811 */
+  {0x2f812, 1, 5191}, /* CJK COMPATIBILITY IDEOGRAPH-2F812 */
+  {0x2f813, 1, 5192}, /* CJK COMPATIBILITY IDEOGRAPH-2F813 */
+  {0x2f814, 1, 5193}, /* CJK COMPATIBILITY IDEOGRAPH-2F814 */
+  {0x2f815, 1, 5194}, /* CJK COMPATIBILITY IDEOGRAPH-2F815 */
+  {0x2f816, 1, 5195}, /* CJK COMPATIBILITY IDEOGRAPH-2F816 */
+  {0x2f817, 1, 5196}, /* CJK COMPATIBILITY IDEOGRAPH-2F817 */
+  {0x2f818, 1, 5197}, /* CJK COMPATIBILITY IDEOGRAPH-2F818 */
+  {0x2f819, 1, 5198}, /* CJK COMPATIBILITY IDEOGRAPH-2F819 */
+  {0x2f81a, 1, 5199}, /* CJK COMPATIBILITY IDEOGRAPH-2F81A */
+  {0x2f81b, 1, 5200}, /* CJK COMPATIBILITY IDEOGRAPH-2F81B */
+  {0x2f81c, 1, 5201}, /* CJK COMPATIBILITY IDEOGRAPH-2F81C */
+  {0x2f81d, 1, 2389}, /* CJK COMPATIBILITY IDEOGRAPH-2F81D */
+  {0x2f81e, 1, 5202}, /* CJK COMPATIBILITY IDEOGRAPH-2F81E */
+  {0x2f81f, 1, 5203}, /* CJK COMPATIBILITY IDEOGRAPH-2F81F */
+  {0x2f820, 1, 5204}, /* CJK COMPATIBILITY IDEOGRAPH-2F820 */
+  {0x2f821, 1, 5205}, /* CJK COMPATIBILITY IDEOGRAPH-2F821 */
+  {0x2f822, 1, 5206}, /* CJK COMPATIBILITY IDEOGRAPH-2F822 */
+  {0x2f823, 1, 5207}, /* CJK COMPATIBILITY IDEOGRAPH-2F823 */
+  {0x2f824, 1, 5208}, /* CJK COMPATIBILITY IDEOGRAPH-2F824 */
+  {0x2f825, 1, 5209}, /* CJK COMPATIBILITY IDEOGRAPH-2F825 */
+  {0x2f826, 1, 4145}, /* CJK COMPATIBILITY IDEOGRAPH-2F826 */
+  {0x2f827, 1, 4146}, /* CJK COMPATIBILITY IDEOGRAPH-2F827 */
+  {0x2f828, 1, 5210}, /* CJK COMPATIBILITY IDEOGRAPH-2F828 */
+  {0x2f829, 1, 5211}, /* CJK COMPATIBILITY IDEOGRAPH-2F829 */
+  {0x2f82a, 1, 5212}, /* CJK COMPATIBILITY IDEOGRAPH-2F82A */
+  {0x2f82b, 1, 3965}, /* CJK COMPATIBILITY IDEOGRAPH-2F82B */
+  {0x2f82c, 1, 5213}, /* CJK COMPATIBILITY IDEOGRAPH-2F82C */
+  {0x2f82d, 1, 4147}, /* CJK COMPATIBILITY IDEOGRAPH-2F82D */
+  {0x2f82e, 1, 5214}, /* CJK COMPATIBILITY IDEOGRAPH-2F82E */
+  {0x2f82f, 1, 5215}, /* CJK COMPATIBILITY IDEOGRAPH-2F82F */
+  {0x2f830, 1, 5216}, /* CJK COMPATIBILITY IDEOGRAPH-2F830 */
+  {0x2f831, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F831 */
+  {0x2f832, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F832 */
+  {0x2f833, 1, 5217}, /* CJK COMPATIBILITY IDEOGRAPH-2F833 */
+  {0x2f834, 1, 5218}, /* CJK COMPATIBILITY IDEOGRAPH-2F834 */
+  {0x2f835, 1, 5219}, /* CJK COMPATIBILITY IDEOGRAPH-2F835 */
+  {0x2f836, 1, 5220}, /* CJK COMPATIBILITY IDEOGRAPH-2F836 */
+  {0x2f837, 1, 5221}, /* CJK COMPATIBILITY IDEOGRAPH-2F837 */
+  {0x2f838, 1, 5222}, /* CJK COMPATIBILITY IDEOGRAPH-2F838 */
+  {0x2f839, 1, 5223}, /* CJK COMPATIBILITY IDEOGRAPH-2F839 */
+  {0x2f83a, 1, 5224}, /* CJK COMPATIBILITY IDEOGRAPH-2F83A */
+  {0x2f83b, 1, 5225}, /* CJK COMPATIBILITY IDEOGRAPH-2F83B */
+  {0x2f83c, 1, 5226}, /* CJK COMPATIBILITY IDEOGRAPH-2F83C */
+  {0x2f83d, 1, 5227}, /* CJK COMPATIBILITY IDEOGRAPH-2F83D */
+  {0x2f83e, 1, 5228}, /* CJK COMPATIBILITY IDEOGRAPH-2F83E */
+  {0x2f83f, 1, 5229}, /* CJK COMPATIBILITY IDEOGRAPH-2F83F */
+  {0x2f840, 1, 5230}, /* CJK COMPATIBILITY IDEOGRAPH-2F840 */
+  {0x2f841, 1, 5231}, /* CJK COMPATIBILITY IDEOGRAPH-2F841 */
+  {0x2f842, 1, 5232}, /* CJK COMPATIBILITY IDEOGRAPH-2F842 */
+  {0x2f843, 1, 5233}, /* CJK COMPATIBILITY IDEOGRAPH-2F843 */
+  {0x2f844, 1, 5234}, /* CJK COMPATIBILITY IDEOGRAPH-2F844 */
+  {0x2f845, 1, 5235}, /* CJK COMPATIBILITY IDEOGRAPH-2F845 */
+  {0x2f846, 1, 5235}, /* CJK COMPATIBILITY IDEOGRAPH-2F846 */
+  {0x2f847, 1, 5236}, /* CJK COMPATIBILITY IDEOGRAPH-2F847 */
+  {0x2f848, 1, 5237}, /* CJK COMPATIBILITY IDEOGRAPH-2F848 */
+  {0x2f849, 1, 5238}, /* CJK COMPATIBILITY IDEOGRAPH-2F849 */
+  {0x2f84a, 1, 5239}, /* CJK COMPATIBILITY IDEOGRAPH-2F84A */
+  {0x2f84b, 1, 5240}, /* CJK COMPATIBILITY IDEOGRAPH-2F84B */
+  {0x2f84c, 1, 4149}, /* CJK COMPATIBILITY IDEOGRAPH-2F84C */
+  {0x2f84d, 1, 5241}, /* CJK COMPATIBILITY IDEOGRAPH-2F84D */
+  {0x2f84e, 1, 5242}, /* CJK COMPATIBILITY IDEOGRAPH-2F84E */
+  {0x2f84f, 1, 5243}, /* CJK COMPATIBILITY IDEOGRAPH-2F84F */
+  {0x2f850, 1, 4111}, /* CJK COMPATIBILITY IDEOGRAPH-2F850 */
+  {0x2f851, 1, 5244}, /* CJK COMPATIBILITY IDEOGRAPH-2F851 */
+  {0x2f852, 1, 5245}, /* CJK COMPATIBILITY IDEOGRAPH-2F852 */
+  {0x2f853, 1, 5246}, /* CJK COMPATIBILITY IDEOGRAPH-2F853 */
+  {0x2f854, 1, 5247}, /* CJK COMPATIBILITY IDEOGRAPH-2F854 */
+  {0x2f855, 1, 5248}, /* CJK COMPATIBILITY IDEOGRAPH-2F855 */
+  {0x2f856, 1, 5249}, /* CJK COMPATIBILITY IDEOGRAPH-2F856 */
+  {0x2f857, 1, 5250}, /* CJK COMPATIBILITY IDEOGRAPH-2F857 */
+  {0x2f858, 1, 5251}, /* CJK COMPATIBILITY IDEOGRAPH-2F858 */
+  {0x2f859, 1, 5252}, /* CJK COMPATIBILITY IDEOGRAPH-2F859 */
+  {0x2f85a, 1, 5253}, /* CJK COMPATIBILITY IDEOGRAPH-2F85A */
+  {0x2f85b, 1, 5254}, /* CJK COMPATIBILITY IDEOGRAPH-2F85B */
+  {0x2f85c, 1, 5255}, /* CJK COMPATIBILITY IDEOGRAPH-2F85C */
+  {0x2f85d, 1, 5256}, /* CJK COMPATIBILITY IDEOGRAPH-2F85D */
+  {0x2f85e, 1, 5257}, /* CJK COMPATIBILITY IDEOGRAPH-2F85E */
+  {0x2f85f, 1, 5258}, /* CJK COMPATIBILITY IDEOGRAPH-2F85F */
+  {0x2f860, 1, 5259}, /* CJK COMPATIBILITY IDEOGRAPH-2F860 */
+  {0x2f861, 1, 5260}, /* CJK COMPATIBILITY IDEOGRAPH-2F861 */
+  {0x2f862, 1, 5261}, /* CJK COMPATIBILITY IDEOGRAPH-2F862 */
+  {0x2f863, 1, 5262}, /* CJK COMPATIBILITY IDEOGRAPH-2F863 */
+  {0x2f864, 1, 5263}, /* CJK COMPATIBILITY IDEOGRAPH-2F864 */
+  {0x2f865, 1, 5264}, /* CJK COMPATIBILITY IDEOGRAPH-2F865 */
+  {0x2f866, 1, 5265}, /* CJK COMPATIBILITY IDEOGRAPH-2F866 */
+  {0x2f867, 1, 5266}, /* CJK COMPATIBILITY IDEOGRAPH-2F867 */
+  {0x2f868, 1, 5267}, /* CJK COMPATIBILITY IDEOGRAPH-2F868 */
+  {0x2f869, 1, 5268}, /* CJK COMPATIBILITY IDEOGRAPH-2F869 */
+  {0x2f86a, 1, 5269}, /* CJK COMPATIBILITY IDEOGRAPH-2F86A */
+  {0x2f86b, 1, 5269}, /* CJK COMPATIBILITY IDEOGRAPH-2F86B */
+  {0x2f86c, 1, 5270}, /* CJK COMPATIBILITY IDEOGRAPH-2F86C */
+  {0x2f86d, 1, 5271}, /* CJK COMPATIBILITY IDEOGRAPH-2F86D */
+  {0x2f86e, 1, 5272}, /* CJK COMPATIBILITY IDEOGRAPH-2F86E */
+  {0x2f86f, 1, 3961}, /* CJK COMPATIBILITY IDEOGRAPH-2F86F */
+  {0x2f870, 1, 5273}, /* CJK COMPATIBILITY IDEOGRAPH-2F870 */
+  {0x2f871, 1, 5274}, /* CJK COMPATIBILITY IDEOGRAPH-2F871 */
+  {0x2f872, 1, 5275}, /* CJK COMPATIBILITY IDEOGRAPH-2F872 */
+  {0x2f873, 1, 5276}, /* CJK COMPATIBILITY IDEOGRAPH-2F873 */
+  {0x2f874, 1, 5277}, /* CJK COMPATIBILITY IDEOGRAPH-2F874 */
+  {0x2f875, 1, 2415}, /* CJK COMPATIBILITY IDEOGRAPH-2F875 */
+  {0x2f876, 1, 5278}, /* CJK COMPATIBILITY IDEOGRAPH-2F876 */
+  {0x2f877, 1, 5279}, /* CJK COMPATIBILITY IDEOGRAPH-2F877 */
+  {0x2f878, 1, 2417}, /* CJK COMPATIBILITY IDEOGRAPH-2F878 */
+  {0x2f879, 1, 5280}, /* CJK COMPATIBILITY IDEOGRAPH-2F879 */
+  {0x2f87a, 1, 5281}, /* CJK COMPATIBILITY IDEOGRAPH-2F87A */
+  {0x2f87b, 1, 5282}, /* CJK COMPATIBILITY IDEOGRAPH-2F87B */
+  {0x2f87c, 1, 5283}, /* CJK COMPATIBILITY IDEOGRAPH-2F87C */
+  {0x2f87d, 1, 5284}, /* CJK COMPATIBILITY IDEOGRAPH-2F87D */
+  {0x2f87e, 1, 5285}, /* CJK COMPATIBILITY IDEOGRAPH-2F87E */
+  {0x2f87f, 1, 5286}, /* CJK COMPATIBILITY IDEOGRAPH-2F87F */
+  {0x2f880, 1, 5287}, /* CJK COMPATIBILITY IDEOGRAPH-2F880 */
+  {0x2f881, 1, 5288}, /* CJK COMPATIBILITY IDEOGRAPH-2F881 */
+  {0x2f882, 1, 5289}, /* CJK COMPATIBILITY IDEOGRAPH-2F882 */
+  {0x2f883, 1, 5290}, /* CJK COMPATIBILITY IDEOGRAPH-2F883 */
+  {0x2f884, 1, 5291}, /* CJK COMPATIBILITY IDEOGRAPH-2F884 */
+  {0x2f885, 1, 5292}, /* CJK COMPATIBILITY IDEOGRAPH-2F885 */
+  {0x2f886, 1, 5293}, /* CJK COMPATIBILITY IDEOGRAPH-2F886 */
+  {0x2f887, 1, 5294}, /* CJK COMPATIBILITY IDEOGRAPH-2F887 */
+  {0x2f888, 1, 5295}, /* CJK COMPATIBILITY IDEOGRAPH-2F888 */
+  {0x2f889, 1, 5296}, /* CJK COMPATIBILITY IDEOGRAPH-2F889 */
+  {0x2f88a, 1, 5297}, /* CJK COMPATIBILITY IDEOGRAPH-2F88A */
+  {0x2f88b, 1, 5298}, /* CJK COMPATIBILITY IDEOGRAPH-2F88B */
+  {0x2f88c, 1, 5299}, /* CJK COMPATIBILITY IDEOGRAPH-2F88C */
+  {0x2f88d, 1, 5300}, /* CJK COMPATIBILITY IDEOGRAPH-2F88D */
+  {0x2f88e, 1, 3909}, /* CJK COMPATIBILITY IDEOGRAPH-2F88E */
+  {0x2f88f, 1, 5301}, /* CJK COMPATIBILITY IDEOGRAPH-2F88F */
+  {0x2f890, 1, 2427}, /* CJK COMPATIBILITY IDEOGRAPH-2F890 */
+  {0x2f891, 1, 5302}, /* CJK COMPATIBILITY IDEOGRAPH-2F891 */
+  {0x2f892, 1, 5302}, /* CJK COMPATIBILITY IDEOGRAPH-2F892 */
+  {0x2f893, 1, 5303}, /* CJK COMPATIBILITY IDEOGRAPH-2F893 */
+  {0x2f894, 1, 5304}, /* CJK COMPATIBILITY IDEOGRAPH-2F894 */
+  {0x2f895, 1, 5304}, /* CJK COMPATIBILITY IDEOGRAPH-2F895 */
+  {0x2f896, 1, 5305}, /* CJK COMPATIBILITY IDEOGRAPH-2F896 */
+  {0x2f897, 1, 5306}, /* CJK COMPATIBILITY IDEOGRAPH-2F897 */
+  {0x2f898, 1, 5307}, /* CJK COMPATIBILITY IDEOGRAPH-2F898 */
+  {0x2f899, 1, 5308}, /* CJK COMPATIBILITY IDEOGRAPH-2F899 */
+  {0x2f89a, 1, 5309}, /* CJK COMPATIBILITY IDEOGRAPH-2F89A */
+  {0x2f89b, 1, 5310}, /* CJK COMPATIBILITY IDEOGRAPH-2F89B */
+  {0x2f89c, 1, 5311}, /* CJK COMPATIBILITY IDEOGRAPH-2F89C */
+  {0x2f89d, 1, 5312}, /* CJK COMPATIBILITY IDEOGRAPH-2F89D */
+  {0x2f89e, 1, 5313}, /* CJK COMPATIBILITY IDEOGRAPH-2F89E */
+  {0x2f89f, 1, 5314}, /* CJK COMPATIBILITY IDEOGRAPH-2F89F */
+  {0x2f8a0, 1, 5315}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A0 */
+  {0x2f8a1, 1, 5316}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A1 */
+  {0x2f8a2, 1, 5317}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A2 */
+  {0x2f8a3, 1, 4154}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A3 */
+  {0x2f8a4, 1, 5318}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A4 */
+  {0x2f8a5, 1, 5319}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A5 */
+  {0x2f8a6, 1, 5320}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A6 */
+  {0x2f8a7, 1, 5321}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A7 */
+  {0x2f8a8, 1, 5322}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A8 */
+  {0x2f8a9, 1, 5321}, /* CJK COMPATIBILITY IDEOGRAPH-2F8A9 */
+  {0x2f8aa, 1, 5323}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AA */
+  {0x2f8ab, 1, 4156}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AB */
+  {0x2f8ac, 1, 5324}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AC */
+  {0x2f8ad, 1, 5325}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AD */
+  {0x2f8ae, 1, 5326}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AE */
+  {0x2f8af, 1, 5327}, /* CJK COMPATIBILITY IDEOGRAPH-2F8AF */
+  {0x2f8b0, 1, 4157}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B0 */
+  {0x2f8b1, 1, 3882}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B1 */
+  {0x2f8b2, 1, 3553}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B2 */
+  {0x2f8b3, 1, 5328}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B3 */
+  {0x2f8b4, 1, 5329}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B4 */
+  {0x2f8b5, 1, 5330}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B5 */
+  {0x2f8b6, 1, 5331}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B6 */
+  {0x2f8b7, 1, 5332}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B7 */
+  {0x2f8b8, 1, 5333}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B8 */
+  {0x2f8b9, 1, 5334}, /* CJK COMPATIBILITY IDEOGRAPH-2F8B9 */
+  {0x2f8ba, 1, 5335}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BA */
+  {0x2f8bb, 1, 5336}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BB */
+  {0x2f8bc, 1, 5337}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BC */
+  {0x2f8bd, 1, 5338}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BD */
+  {0x2f8be, 1, 5339}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BE */
+  {0x2f8bf, 1, 5340}, /* CJK COMPATIBILITY IDEOGRAPH-2F8BF */
+  {0x2f8c0, 1, 5341}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C0 */
+  {0x2f8c1, 1, 5342}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C1 */
+  {0x2f8c2, 1, 5343}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C2 */
+  {0x2f8c3, 1, 5344}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C3 */
+  {0x2f8c4, 1, 5345}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C4 */
+  {0x2f8c5, 1, 5346}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C5 */
+  {0x2f8c6, 1, 5347}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C6 */
+  {0x2f8c7, 1, 5348}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C7 */
+  {0x2f8c8, 1, 4158}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C8 */
+  {0x2f8c9, 1, 5349}, /* CJK COMPATIBILITY IDEOGRAPH-2F8C9 */
+  {0x2f8ca, 1, 5350}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CA */
+  {0x2f8cb, 1, 5351}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CB */
+  {0x2f8cc, 1, 5352}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CC */
+  {0x2f8cd, 1, 5353}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CD */
+  {0x2f8ce, 1, 5354}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CE */
+  {0x2f8cf, 1, 4160}, /* CJK COMPATIBILITY IDEOGRAPH-2F8CF */
+  {0x2f8d0, 1, 5355}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D0 */
+  {0x2f8d1, 1, 5356}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D1 */
+  {0x2f8d2, 1, 5357}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D2 */
+  {0x2f8d3, 1, 5358}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D3 */
+  {0x2f8d4, 1, 5359}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D4 */
+  {0x2f8d5, 1, 5360}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D5 */
+  {0x2f8d6, 1, 5361}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D6 */
+  {0x2f8d7, 1, 5362}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D7 */
+  {0x2f8d8, 1, 3910}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D8 */
+  {0x2f8d9, 1, 5363}, /* CJK COMPATIBILITY IDEOGRAPH-2F8D9 */
+  {0x2f8da, 1, 5364}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DA */
+  {0x2f8db, 1, 5365}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DB */
+  {0x2f8dc, 1, 5366}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DC */
+  {0x2f8dd, 1, 5367}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DD */
+  {0x2f8de, 1, 5368}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DE */
+  {0x2f8df, 1, 5369}, /* CJK COMPATIBILITY IDEOGRAPH-2F8DF */
+  {0x2f8e0, 1, 5370}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E0 */
+  {0x2f8e1, 1, 5371}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E1 */
+  {0x2f8e2, 1, 4161}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E2 */
+  {0x2f8e3, 1, 5372}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E3 */
+  {0x2f8e4, 1, 5373}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E4 */
+  {0x2f8e5, 1, 5374}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E5 */
+  {0x2f8e6, 1, 5375}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E6 */
+  {0x2f8e7, 1, 5376}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E7 */
+  {0x2f8e8, 1, 5377}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E8 */
+  {0x2f8e9, 1, 5378}, /* CJK COMPATIBILITY IDEOGRAPH-2F8E9 */
+  {0x2f8ea, 1, 5379}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EA */
+  {0x2f8eb, 1, 5380}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EB */
+  {0x2f8ec, 1, 5381}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EC */
+  {0x2f8ed, 1, 5382}, /* CJK COMPATIBILITY IDEOGRAPH-2F8ED */
+  {0x2f8ee, 1, 5383}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EE */
+  {0x2f8ef, 1, 5384}, /* CJK COMPATIBILITY IDEOGRAPH-2F8EF */
+  {0x2f8f0, 1, 5385}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F0 */
+  {0x2f8f1, 1, 5386}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F1 */
+  {0x2f8f2, 1, 5387}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F2 */
+  {0x2f8f3, 1, 5388}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F3 */
+  {0x2f8f4, 1, 5389}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F4 */
+  {0x2f8f5, 1, 3978}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F5 */
+  {0x2f8f6, 1, 5390}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F6 */
+  {0x2f8f7, 1, 5391}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F7 */
+  {0x2f8f8, 1, 5392}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F8 */
+  {0x2f8f9, 1, 5393}, /* CJK COMPATIBILITY IDEOGRAPH-2F8F9 */
+  {0x2f8fa, 1, 5394}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FA */
+  {0x2f8fb, 1, 5395}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FB */
+  {0x2f8fc, 1, 5396}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FC */
+  {0x2f8fd, 1, 5397}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FD */
+  {0x2f8fe, 1, 5398}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FE */
+  {0x2f8ff, 1, 5399}, /* CJK COMPATIBILITY IDEOGRAPH-2F8FF */
+  {0x2f900, 1, 5400}, /* CJK COMPATIBILITY IDEOGRAPH-2F900 */
+  {0x2f901, 1, 4162}, /* CJK COMPATIBILITY IDEOGRAPH-2F901 */
+  {0x2f902, 1, 4061}, /* CJK COMPATIBILITY IDEOGRAPH-2F902 */
+  {0x2f903, 1, 5401}, /* CJK COMPATIBILITY IDEOGRAPH-2F903 */
+  {0x2f904, 1, 5402}, /* CJK COMPATIBILITY IDEOGRAPH-2F904 */
+  {0x2f905, 1, 5403}, /* CJK COMPATIBILITY IDEOGRAPH-2F905 */
+  {0x2f906, 1, 5404}, /* CJK COMPATIBILITY IDEOGRAPH-2F906 */
+  {0x2f907, 1, 5405}, /* CJK COMPATIBILITY IDEOGRAPH-2F907 */
+  {0x2f908, 1, 5406}, /* CJK COMPATIBILITY IDEOGRAPH-2F908 */
+  {0x2f909, 1, 5407}, /* CJK COMPATIBILITY IDEOGRAPH-2F909 */
+  {0x2f90a, 1, 5408}, /* CJK COMPATIBILITY IDEOGRAPH-2F90A */
+  {0x2f90b, 1, 5409}, /* CJK COMPATIBILITY IDEOGRAPH-2F90B */
+  {0x2f90c, 1, 5410}, /* CJK COMPATIBILITY IDEOGRAPH-2F90C */
+  {0x2f90d, 1, 5411}, /* CJK COMPATIBILITY IDEOGRAPH-2F90D */
+  {0x2f90e, 1, 5412}, /* CJK COMPATIBILITY IDEOGRAPH-2F90E */
+  {0x2f90f, 1, 5413}, /* CJK COMPATIBILITY IDEOGRAPH-2F90F */
+  {0x2f910, 1, 5414}, /* CJK COMPATIBILITY IDEOGRAPH-2F910 */
+  {0x2f911, 1, 5415}, /* CJK COMPATIBILITY IDEOGRAPH-2F911 */
+  {0x2f912, 1, 5416}, /* CJK COMPATIBILITY IDEOGRAPH-2F912 */
+  {0x2f913, 1, 5417}, /* CJK COMPATIBILITY IDEOGRAPH-2F913 */
+  {0x2f914, 1, 5418}, /* CJK COMPATIBILITY IDEOGRAPH-2F914 */
+  {0x2f915, 1, 5419}, /* CJK COMPATIBILITY IDEOGRAPH-2F915 */
+  {0x2f916, 1, 5420}, /* CJK COMPATIBILITY IDEOGRAPH-2F916 */
+  {0x2f917, 1, 5421}, /* CJK COMPATIBILITY IDEOGRAPH-2F917 */
+  {0x2f918, 1, 5422}, /* CJK COMPATIBILITY IDEOGRAPH-2F918 */
+  {0x2f919, 1, 5423}, /* CJK COMPATIBILITY IDEOGRAPH-2F919 */
+  {0x2f91a, 1, 5424}, /* CJK COMPATIBILITY IDEOGRAPH-2F91A */
+  {0x2f91b, 1, 5425}, /* CJK COMPATIBILITY IDEOGRAPH-2F91B */
+  {0x2f91c, 1, 5426}, /* CJK COMPATIBILITY IDEOGRAPH-2F91C */
+  {0x2f91d, 1, 5427}, /* CJK COMPATIBILITY IDEOGRAPH-2F91D */
+  {0x2f91e, 1, 5428}, /* CJK COMPATIBILITY IDEOGRAPH-2F91E */
+  {0x2f91f, 1, 5429}, /* CJK COMPATIBILITY IDEOGRAPH-2F91F */
+  {0x2f920, 1, 5430}, /* CJK COMPATIBILITY IDEOGRAPH-2F920 */
+  {0x2f921, 1, 5431}, /* CJK COMPATIBILITY IDEOGRAPH-2F921 */
+  {0x2f922, 1, 5432}, /* CJK COMPATIBILITY IDEOGRAPH-2F922 */
+  {0x2f923, 1, 5433}, /* CJK COMPATIBILITY IDEOGRAPH-2F923 */
+  {0x2f924, 1, 5434}, /* CJK COMPATIBILITY IDEOGRAPH-2F924 */
+  {0x2f925, 1, 5435}, /* CJK COMPATIBILITY IDEOGRAPH-2F925 */
+  {0x2f926, 1, 5436}, /* CJK COMPATIBILITY IDEOGRAPH-2F926 */
+  {0x2f927, 1, 5437}, /* CJK COMPATIBILITY IDEOGRAPH-2F927 */
+  {0x2f928, 1, 5438}, /* CJK COMPATIBILITY IDEOGRAPH-2F928 */
+  {0x2f929, 1, 5439}, /* CJK COMPATIBILITY IDEOGRAPH-2F929 */
+  {0x2f92a, 1, 5440}, /* CJK COMPATIBILITY IDEOGRAPH-2F92A */
+  {0x2f92b, 1, 5441}, /* CJK COMPATIBILITY IDEOGRAPH-2F92B */
+  {0x2f92c, 1, 5442}, /* CJK COMPATIBILITY IDEOGRAPH-2F92C */
+  {0x2f92d, 1, 5442}, /* CJK COMPATIBILITY IDEOGRAPH-2F92D */
+  {0x2f92e, 1, 5443}, /* CJK COMPATIBILITY IDEOGRAPH-2F92E */
+  {0x2f92f, 1, 5444}, /* CJK COMPATIBILITY IDEOGRAPH-2F92F */
+  {0x2f930, 1, 5445}, /* CJK COMPATIBILITY IDEOGRAPH-2F930 */
+  {0x2f931, 1, 5446}, /* CJK COMPATIBILITY IDEOGRAPH-2F931 */
+  {0x2f932, 1, 5447}, /* CJK COMPATIBILITY IDEOGRAPH-2F932 */
+  {0x2f933, 1, 5448}, /* CJK COMPATIBILITY IDEOGRAPH-2F933 */
+  {0x2f934, 1, 5449}, /* CJK COMPATIBILITY IDEOGRAPH-2F934 */
+  {0x2f935, 1, 5450}, /* CJK COMPATIBILITY IDEOGRAPH-2F935 */
+  {0x2f936, 1, 5451}, /* CJK COMPATIBILITY IDEOGRAPH-2F936 */
+  {0x2f937, 1, 5452}, /* CJK COMPATIBILITY IDEOGRAPH-2F937 */
+  {0x2f938, 1, 3964}, /* CJK COMPATIBILITY IDEOGRAPH-2F938 */
+  {0x2f939, 1, 5453}, /* CJK COMPATIBILITY IDEOGRAPH-2F939 */
+  {0x2f93a, 1, 5454}, /* CJK COMPATIBILITY IDEOGRAPH-2F93A */
+  {0x2f93b, 1, 5455}, /* CJK COMPATIBILITY IDEOGRAPH-2F93B */
+  {0x2f93c, 1, 5456}, /* CJK COMPATIBILITY IDEOGRAPH-2F93C */
+  {0x2f93d, 1, 5457}, /* CJK COMPATIBILITY IDEOGRAPH-2F93D */
+  {0x2f93e, 1, 5458}, /* CJK COMPATIBILITY IDEOGRAPH-2F93E */
+  {0x2f93f, 1, 5459}, /* CJK COMPATIBILITY IDEOGRAPH-2F93F */
+  {0x2f940, 1, 5460}, /* CJK COMPATIBILITY IDEOGRAPH-2F940 */
+  {0x2f941, 1, 5461}, /* CJK COMPATIBILITY IDEOGRAPH-2F941 */
+  {0x2f942, 1, 5462}, /* CJK COMPATIBILITY IDEOGRAPH-2F942 */
+  {0x2f943, 1, 5463}, /* CJK COMPATIBILITY IDEOGRAPH-2F943 */
+  {0x2f944, 1, 5464}, /* CJK COMPATIBILITY IDEOGRAPH-2F944 */
+  {0x2f945, 1, 5465}, /* CJK COMPATIBILITY IDEOGRAPH-2F945 */
+  {0x2f946, 1, 5466}, /* CJK COMPATIBILITY IDEOGRAPH-2F946 */
+  {0x2f947, 1, 5466}, /* CJK COMPATIBILITY IDEOGRAPH-2F947 */
+  {0x2f948, 1, 5467}, /* CJK COMPATIBILITY IDEOGRAPH-2F948 */
+  {0x2f949, 1, 5468}, /* CJK COMPATIBILITY IDEOGRAPH-2F949 */
+  {0x2f94a, 1, 5469}, /* CJK COMPATIBILITY IDEOGRAPH-2F94A */
+  {0x2f94b, 1, 5470}, /* CJK COMPATIBILITY IDEOGRAPH-2F94B */
+  {0x2f94c, 1, 5471}, /* CJK COMPATIBILITY IDEOGRAPH-2F94C */
+  {0x2f94d, 1, 5472}, /* CJK COMPATIBILITY IDEOGRAPH-2F94D */
+  {0x2f94e, 1, 5473}, /* CJK COMPATIBILITY IDEOGRAPH-2F94E */
+  {0x2f94f, 1, 3927}, /* CJK COMPATIBILITY IDEOGRAPH-2F94F */
+  {0x2f950, 1, 5474}, /* CJK COMPATIBILITY IDEOGRAPH-2F950 */
+  {0x2f951, 1, 5475}, /* CJK COMPATIBILITY IDEOGRAPH-2F951 */
+  {0x2f952, 1, 5476}, /* CJK COMPATIBILITY IDEOGRAPH-2F952 */
+  {0x2f953, 1, 4172}, /* CJK COMPATIBILITY IDEOGRAPH-2F953 */
+  {0x2f954, 1, 5477}, /* CJK COMPATIBILITY IDEOGRAPH-2F954 */
+  {0x2f955, 1, 5478}, /* CJK COMPATIBILITY IDEOGRAPH-2F955 */
+  {0x2f956, 1, 4131}, /* CJK COMPATIBILITY IDEOGRAPH-2F956 */
+  {0x2f957, 1, 5479}, /* CJK COMPATIBILITY IDEOGRAPH-2F957 */
+  {0x2f958, 1, 5480}, /* CJK COMPATIBILITY IDEOGRAPH-2F958 */
+  {0x2f959, 1, 4175}, /* CJK COMPATIBILITY IDEOGRAPH-2F959 */
+  {0x2f95a, 1, 5481}, /* CJK COMPATIBILITY IDEOGRAPH-2F95A */
+  {0x2f95b, 1, 5482}, /* CJK COMPATIBILITY IDEOGRAPH-2F95B */
+  {0x2f95c, 1, 5483}, /* CJK COMPATIBILITY IDEOGRAPH-2F95C */
+  {0x2f95d, 1, 5484}, /* CJK COMPATIBILITY IDEOGRAPH-2F95D */
+  {0x2f95e, 1, 5484}, /* CJK COMPATIBILITY IDEOGRAPH-2F95E */
+  {0x2f95f, 1, 5485}, /* CJK COMPATIBILITY IDEOGRAPH-2F95F */
+  {0x2f960, 1, 5486}, /* CJK COMPATIBILITY IDEOGRAPH-2F960 */
+  {0x2f961, 1, 5487}, /* CJK COMPATIBILITY IDEOGRAPH-2F961 */
+  {0x2f962, 1, 5488}, /* CJK COMPATIBILITY IDEOGRAPH-2F962 */
+  {0x2f963, 1, 5489}, /* CJK COMPATIBILITY IDEOGRAPH-2F963 */
+  {0x2f964, 1, 5490}, /* CJK COMPATIBILITY IDEOGRAPH-2F964 */
+  {0x2f965, 1, 5491}, /* CJK COMPATIBILITY IDEOGRAPH-2F965 */
+  {0x2f966, 1, 5492}, /* CJK COMPATIBILITY IDEOGRAPH-2F966 */
+  {0x2f967, 1, 5493}, /* CJK COMPATIBILITY IDEOGRAPH-2F967 */
+  {0x2f968, 1, 5494}, /* CJK COMPATIBILITY IDEOGRAPH-2F968 */
+  {0x2f969, 1, 5495}, /* CJK COMPATIBILITY IDEOGRAPH-2F969 */
+  {0x2f96a, 1, 5496}, /* CJK COMPATIBILITY IDEOGRAPH-2F96A */
+  {0x2f96b, 1, 5497}, /* CJK COMPATIBILITY IDEOGRAPH-2F96B */
+  {0x2f96c, 1, 5498}, /* CJK COMPATIBILITY IDEOGRAPH-2F96C */
+  {0x2f96d, 1, 5499}, /* CJK COMPATIBILITY IDEOGRAPH-2F96D */
+  {0x2f96e, 1, 5500}, /* CJK COMPATIBILITY IDEOGRAPH-2F96E */
+  {0x2f96f, 1, 5501}, /* CJK COMPATIBILITY IDEOGRAPH-2F96F */
+  {0x2f970, 1, 5502}, /* CJK COMPATIBILITY IDEOGRAPH-2F970 */
+  {0x2f971, 1, 5503}, /* CJK COMPATIBILITY IDEOGRAPH-2F971 */
+  {0x2f972, 1, 5504}, /* CJK COMPATIBILITY IDEOGRAPH-2F972 */
+  {0x2f973, 1, 5505}, /* CJK COMPATIBILITY IDEOGRAPH-2F973 */
+  {0x2f974, 1, 5506}, /* CJK COMPATIBILITY IDEOGRAPH-2F974 */
+  {0x2f975, 1, 5507}, /* CJK COMPATIBILITY IDEOGRAPH-2F975 */
+  {0x2f976, 1, 5508}, /* CJK COMPATIBILITY IDEOGRAPH-2F976 */
+  {0x2f977, 1, 5509}, /* CJK COMPATIBILITY IDEOGRAPH-2F977 */
+  {0x2f978, 1, 5510}, /* CJK COMPATIBILITY IDEOGRAPH-2F978 */
+  {0x2f979, 1, 5511}, /* CJK COMPATIBILITY IDEOGRAPH-2F979 */
+  {0x2f97a, 1, 4181}, /* CJK COMPATIBILITY IDEOGRAPH-2F97A */
+  {0x2f97b, 1, 5512}, /* CJK COMPATIBILITY IDEOGRAPH-2F97B */
+  {0x2f97c, 1, 5513}, /* CJK COMPATIBILITY IDEOGRAPH-2F97C */
+  {0x2f97d, 1, 5514}, /* CJK COMPATIBILITY IDEOGRAPH-2F97D */
+  {0x2f97e, 1, 5515}, /* CJK COMPATIBILITY IDEOGRAPH-2F97E */
+  {0x2f97f, 1, 5516}, /* CJK COMPATIBILITY IDEOGRAPH-2F97F */
+  {0x2f980, 1, 5517}, /* CJK COMPATIBILITY IDEOGRAPH-2F980 */
+  {0x2f981, 1, 5518}, /* CJK COMPATIBILITY IDEOGRAPH-2F981 */
+  {0x2f982, 1, 5519}, /* CJK COMPATIBILITY IDEOGRAPH-2F982 */
+  {0x2f983, 1, 5520}, /* CJK COMPATIBILITY IDEOGRAPH-2F983 */
+  {0x2f984, 1, 5521}, /* CJK COMPATIBILITY IDEOGRAPH-2F984 */
+  {0x2f985, 1, 5522}, /* CJK COMPATIBILITY IDEOGRAPH-2F985 */
+  {0x2f986, 1, 5523}, /* CJK COMPATIBILITY IDEOGRAPH-2F986 */
+  {0x2f987, 1, 5524}, /* CJK COMPATIBILITY IDEOGRAPH-2F987 */
+  {0x2f988, 1, 5525}, /* CJK COMPATIBILITY IDEOGRAPH-2F988 */
+  {0x2f989, 1, 5526}, /* CJK COMPATIBILITY IDEOGRAPH-2F989 */
+  {0x2f98a, 1, 5527}, /* CJK COMPATIBILITY IDEOGRAPH-2F98A */
+  {0x2f98b, 1, 5303}, /* CJK COMPATIBILITY IDEOGRAPH-2F98B */
+  {0x2f98c, 1, 5528}, /* CJK COMPATIBILITY IDEOGRAPH-2F98C */
+  {0x2f98d, 1, 5529}, /* CJK COMPATIBILITY IDEOGRAPH-2F98D */
+  {0x2f98e, 1, 5530}, /* CJK COMPATIBILITY IDEOGRAPH-2F98E */
+  {0x2f98f, 1, 5531}, /* CJK COMPATIBILITY IDEOGRAPH-2F98F */
+  {0x2f990, 1, 5532}, /* CJK COMPATIBILITY IDEOGRAPH-2F990 */
+  {0x2f991, 1, 5533}, /* CJK COMPATIBILITY IDEOGRAPH-2F991 */
+  {0x2f992, 1, 5534}, /* CJK COMPATIBILITY IDEOGRAPH-2F992 */
+  {0x2f993, 1, 5535}, /* CJK COMPATIBILITY IDEOGRAPH-2F993 */
+  {0x2f994, 1, 5536}, /* CJK COMPATIBILITY IDEOGRAPH-2F994 */
+  {0x2f995, 1, 5537}, /* CJK COMPATIBILITY IDEOGRAPH-2F995 */
+  {0x2f996, 1, 5538}, /* CJK COMPATIBILITY IDEOGRAPH-2F996 */
+  {0x2f997, 1, 5539}, /* CJK COMPATIBILITY IDEOGRAPH-2F997 */
+  {0x2f998, 1, 3981}, /* CJK COMPATIBILITY IDEOGRAPH-2F998 */
+  {0x2f999, 1, 5540}, /* CJK COMPATIBILITY IDEOGRAPH-2F999 */
+  {0x2f99a, 1, 5541}, /* CJK COMPATIBILITY IDEOGRAPH-2F99A */
+  {0x2f99b, 1, 5542}, /* CJK COMPATIBILITY IDEOGRAPH-2F99B */
+  {0x2f99c, 1, 5543}, /* CJK COMPATIBILITY IDEOGRAPH-2F99C */
+  {0x2f99d, 1, 5544}, /* CJK COMPATIBILITY IDEOGRAPH-2F99D */
+  {0x2f99e, 1, 5545}, /* CJK COMPATIBILITY IDEOGRAPH-2F99E */
+  {0x2f99f, 1, 4184}, /* CJK COMPATIBILITY IDEOGRAPH-2F99F */
+  {0x2f9a0, 1, 5546}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A0 */
+  {0x2f9a1, 1, 5547}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A1 */
+  {0x2f9a2, 1, 5548}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A2 */
+  {0x2f9a3, 1, 5549}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A3 */
+  {0x2f9a4, 1, 5550}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A4 */
+  {0x2f9a5, 1, 5551}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A5 */
+  {0x2f9a6, 1, 5552}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A6 */
+  {0x2f9a7, 1, 5553}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A7 */
+  {0x2f9a8, 1, 5554}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A8 */
+  {0x2f9a9, 1, 5555}, /* CJK COMPATIBILITY IDEOGRAPH-2F9A9 */
+  {0x2f9aa, 1, 5556}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AA */
+  {0x2f9ab, 1, 5557}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AB */
+  {0x2f9ac, 1, 5558}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AC */
+  {0x2f9ad, 1, 5559}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AD */
+  {0x2f9ae, 1, 5560}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AE */
+  {0x2f9af, 1, 5561}, /* CJK COMPATIBILITY IDEOGRAPH-2F9AF */
+  {0x2f9b0, 1, 5562}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B0 */
+  {0x2f9b1, 1, 5563}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B1 */
+  {0x2f9b2, 1, 5564}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B2 */
+  {0x2f9b3, 1, 5565}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B3 */
+  {0x2f9b4, 1, 3922}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B4 */
+  {0x2f9b5, 1, 5566}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B5 */
+  {0x2f9b6, 1, 5567}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B6 */
+  {0x2f9b7, 1, 5568}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B7 */
+  {0x2f9b8, 1, 5569}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B8 */
+  {0x2f9b9, 1, 5570}, /* CJK COMPATIBILITY IDEOGRAPH-2F9B9 */
+  {0x2f9ba, 1, 5571}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BA */
+  {0x2f9bb, 1, 5572}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BB */
+  {0x2f9bc, 1, 5573}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BC */
+  {0x2f9bd, 1, 5574}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BD */
+  {0x2f9be, 1, 5575}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BE */
+  {0x2f9bf, 1, 5576}, /* CJK COMPATIBILITY IDEOGRAPH-2F9BF */
+  {0x2f9c0, 1, 5577}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C0 */
+  {0x2f9c1, 1, 5578}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C1 */
+  {0x2f9c2, 1, 5579}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C2 */
+  {0x2f9c3, 1, 5580}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C3 */
+  {0x2f9c4, 1, 2517}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C4 */
+  {0x2f9c5, 1, 5581}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C5 */
+  {0x2f9c6, 1, 5582}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C6 */
+  {0x2f9c7, 1, 5583}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C7 */
+  {0x2f9c8, 1, 5584}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C8 */
+  {0x2f9c9, 1, 5585}, /* CJK COMPATIBILITY IDEOGRAPH-2F9C9 */
+  {0x2f9ca, 1, 5586}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CA */
+  {0x2f9cb, 1, 5587}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CB */
+  {0x2f9cc, 1, 5588}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CC */
+  {0x2f9cd, 1, 5589}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CD */
+  {0x2f9ce, 1, 5590}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CE */
+  {0x2f9cf, 1, 5591}, /* CJK COMPATIBILITY IDEOGRAPH-2F9CF */
+  {0x2f9d0, 1, 5592}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D0 */
+  {0x2f9d1, 1, 5593}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D1 */
+  {0x2f9d2, 1, 2524}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D2 */
+  {0x2f9d3, 1, 5594}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D3 */
+  {0x2f9d4, 1, 5595}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D4 */
+  {0x2f9d5, 1, 5596}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D5 */
+  {0x2f9d6, 1, 5597}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D6 */
+  {0x2f9d7, 1, 5598}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D7 */
+  {0x2f9d8, 1, 5599}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D8 */
+  {0x2f9d9, 1, 5600}, /* CJK COMPATIBILITY IDEOGRAPH-2F9D9 */
+  {0x2f9da, 1, 5601}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DA */
+  {0x2f9db, 1, 5602}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DB */
+  {0x2f9dc, 1, 5603}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DC */
+  {0x2f9dd, 1, 5604}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DD */
+  {0x2f9de, 1, 5605}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DE */
+  {0x2f9df, 1, 5606}, /* CJK COMPATIBILITY IDEOGRAPH-2F9DF */
+  {0x2f9e0, 1, 5607}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E0 */
+  {0x2f9e1, 1, 5608}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E1 */
+  {0x2f9e2, 1, 5609}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E2 */
+  {0x2f9e3, 1, 5610}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E3 */
+  {0x2f9e4, 1, 5611}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E4 */
+  {0x2f9e5, 1, 5612}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E5 */
+  {0x2f9e6, 1, 5613}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E6 */
+  {0x2f9e7, 1, 5614}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E7 */
+  {0x2f9e8, 1, 5615}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E8 */
+  {0x2f9e9, 1, 5616}, /* CJK COMPATIBILITY IDEOGRAPH-2F9E9 */
+  {0x2f9ea, 1, 5617}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EA */
+  {0x2f9eb, 1, 5618}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EB */
+  {0x2f9ec, 1, 5619}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EC */
+  {0x2f9ed, 1, 5620}, /* CJK COMPATIBILITY IDEOGRAPH-2F9ED */
+  {0x2f9ee, 1, 5621}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EE */
+  {0x2f9ef, 1, 5622}, /* CJK COMPATIBILITY IDEOGRAPH-2F9EF */
+  {0x2f9f0, 1, 5623}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F0 */
+  {0x2f9f1, 1, 5624}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F1 */
+  {0x2f9f2, 1, 5625}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F2 */
+  {0x2f9f3, 1, 5626}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F3 */
+  {0x2f9f4, 1, 5627}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F4 */
+  {0x2f9f5, 1, 5628}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F5 */
+  {0x2f9f6, 1, 5629}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F6 */
+  {0x2f9f7, 1, 5630}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F7 */
+  {0x2f9f8, 1, 5631}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F8 */
+  {0x2f9f9, 1, 5632}, /* CJK COMPATIBILITY IDEOGRAPH-2F9F9 */
+  {0x2f9fa, 1, 5633}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FA */
+  {0x2f9fb, 1, 5634}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FB */
+  {0x2f9fc, 1, 5635}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FC */
+  {0x2f9fd, 1, 5636}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FD */
+  {0x2f9fe, 1, 5637}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FE */
+  {0x2f9ff, 1, 5637}, /* CJK COMPATIBILITY IDEOGRAPH-2F9FF */
+  {0x2fa00, 1, 5638}, /* CJK COMPATIBILITY IDEOGRAPH-2FA00 */
+  {0x2fa01, 1, 5639}, /* CJK COMPATIBILITY IDEOGRAPH-2FA01 */
+  {0x2fa02, 1, 5640}, /* CJK COMPATIBILITY IDEOGRAPH-2FA02 */
+  {0x2fa03, 1, 5641}, /* CJK COMPATIBILITY IDEOGRAPH-2FA03 */
+  {0x2fa04, 1, 5642}, /* CJK COMPATIBILITY IDEOGRAPH-2FA04 */
+  {0x2fa05, 1, 5643}, /* CJK COMPATIBILITY IDEOGRAPH-2FA05 */
+  {0x2fa06, 1, 5644}, /* CJK COMPATIBILITY IDEOGRAPH-2FA06 */
+  {0x2fa07, 1, 5645}, /* CJK COMPATIBILITY IDEOGRAPH-2FA07 */
+  {0x2fa08, 1, 5646}, /* CJK COMPATIBILITY IDEOGRAPH-2FA08 */
+  {0x2fa09, 1, 5647}, /* CJK COMPATIBILITY IDEOGRAPH-2FA09 */
+  {0x2fa0a, 1, 5648}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0A */
+  {0x2fa0b, 1, 5649}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0B */
+  {0x2fa0c, 1, 5650}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0C */
+  {0x2fa0d, 1, 5651}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0D */
+  {0x2fa0e, 1, 5652}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0E */
+  {0x2fa0f, 1, 5653}, /* CJK COMPATIBILITY IDEOGRAPH-2FA0F */
+  {0x2fa10, 1, 5654}, /* CJK COMPATIBILITY IDEOGRAPH-2FA10 */
+  {0x2fa11, 1, 5655}, /* CJK COMPATIBILITY IDEOGRAPH-2FA11 */
+  {0x2fa12, 1, 5656}, /* CJK COMPATIBILITY IDEOGRAPH-2FA12 */
+  {0x2fa13, 1, 5657}, /* CJK COMPATIBILITY IDEOGRAPH-2FA13 */
+  {0x2fa14, 1, 5658}, /* CJK COMPATIBILITY IDEOGRAPH-2FA14 */
+  {0x2fa15, 1, 2572}, /* CJK COMPATIBILITY IDEOGRAPH-2FA15 */
+  {0x2fa16, 1, 5659}, /* CJK COMPATIBILITY IDEOGRAPH-2FA16 */
+  {0x2fa17, 1, 2576}, /* CJK COMPATIBILITY IDEOGRAPH-2FA17 */
+  {0x2fa18, 1, 5660}, /* CJK COMPATIBILITY IDEOGRAPH-2FA18 */
+  {0x2fa19, 1, 5661}, /* CJK COMPATIBILITY IDEOGRAPH-2FA19 */
+  {0x2fa1a, 1, 5662}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1A */
+  {0x2fa1b, 1, 5663}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1B */
+  {0x2fa1c, 1, 2581}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1C */
+  {0x2fa1d, 1, 5664}, /* CJK COMPATIBILITY IDEOGRAPH-2FA1D */
+};
+
+const size_t _wind_normalize_table_size = 5224;
+
+const uint32_t _wind_normalize_val_table[] = {
+  0x20,
+  0x20,
+  0x308,
+  0x61,
+  0x20,
+  0x304,
+  0x32,
+  0x33,
+  0x20,
+  0x301,
+  0x3bc,
+  0x20,
+  0x327,
+  0x31,
+  0x6f,
+  0x31,
+  0x2044,
+  0x34,
+  0x31,
+  0x2044,
+  0x32,
+  0x33,
+  0x2044,
+  0x34,
+  0x41,
+  0x300,
+  0x41,
+  0x301,
+  0x41,
+  0x302,
+  0x41,
+  0x303,
+  0x41,
+  0x308,
+  0x41,
+  0x30a,
+  0x43,
+  0x327,
+  0x45,
+  0x300,
+  0x45,
+  0x301,
+  0x45,
+  0x302,
+  0x45,
+  0x308,
+  0x49,
+  0x300,
+  0x49,
+  0x301,
+  0x49,
+  0x302,
+  0x49,
+  0x308,
+  0x4e,
+  0x303,
+  0x4f,
+  0x300,
+  0x4f,
+  0x301,
+  0x4f,
+  0x302,
+  0x4f,
+  0x303,
+  0x4f,
+  0x308,
+  0x55,
+  0x300,
+  0x55,
+  0x301,
+  0x55,
+  0x302,
+  0x55,
+  0x308,
+  0x59,
+  0x301,
+  0x61,
+  0x300,
+  0x61,
+  0x301,
+  0x61,
+  0x302,
+  0x61,
+  0x303,
+  0x61,
+  0x308,
+  0x61,
+  0x30a,
+  0x63,
+  0x327,
+  0x65,
+  0x300,
+  0x65,
+  0x301,
+  0x65,
+  0x302,
+  0x65,
+  0x308,
+  0x69,
+  0x300,
+  0x69,
+  0x301,
+  0x69,
+  0x302,
+  0x69,
+  0x308,
+  0x6e,
+  0x303,
+  0x6f,
+  0x300,
+  0x6f,
+  0x301,
+  0x6f,
+  0x302,
+  0x6f,
+  0x303,
+  0x6f,
+  0x308,
+  0x75,
+  0x300,
+  0x75,
+  0x301,
+  0x75,
+  0x302,
+  0x75,
+  0x308,
+  0x79,
+  0x301,
+  0x79,
+  0x308,
+  0x41,
+  0x304,
+  0x61,
+  0x304,
+  0x41,
+  0x306,
+  0x61,
+  0x306,
+  0x41,
+  0x328,
+  0x61,
+  0x328,
+  0x43,
+  0x301,
+  0x63,
+  0x301,
+  0x43,
+  0x302,
+  0x63,
+  0x302,
+  0x43,
+  0x307,
+  0x63,
+  0x307,
+  0x43,
+  0x30c,
+  0x63,
+  0x30c,
+  0x44,
+  0x30c,
+  0x64,
+  0x30c,
+  0x45,
+  0x304,
+  0x65,
+  0x304,
+  0x45,
+  0x306,
+  0x65,
+  0x306,
+  0x45,
+  0x307,
+  0x65,
+  0x307,
+  0x45,
+  0x328,
+  0x65,
+  0x328,
+  0x45,
+  0x30c,
+  0x65,
+  0x30c,
+  0x47,
+  0x302,
+  0x67,
+  0x302,
+  0x47,
+  0x306,
+  0x67,
+  0x306,
+  0x47,
+  0x307,
+  0x67,
+  0x307,
+  0x47,
+  0x327,
+  0x67,
+  0x327,
+  0x48,
+  0x302,
+  0x68,
+  0x302,
+  0x49,
+  0x303,
+  0x69,
+  0x303,
+  0x49,
+  0x304,
+  0x69,
+  0x304,
+  0x49,
+  0x306,
+  0x69,
+  0x306,
+  0x49,
+  0x328,
+  0x69,
+  0x328,
+  0x49,
+  0x307,
+  0x49,
+  0x4a,
+  0x69,
+  0x6a,
+  0x4a,
+  0x302,
+  0x6a,
+  0x302,
+  0x4b,
+  0x327,
+  0x6b,
+  0x327,
+  0x4c,
+  0x301,
+  0x6c,
+  0x301,
+  0x4c,
+  0x327,
+  0x6c,
+  0x327,
+  0x4c,
+  0x30c,
+  0x6c,
+  0x30c,
+  0x4c,
+  0xb7,
+  0x6c,
+  0xb7,
+  0x4e,
+  0x301,
+  0x6e,
+  0x301,
+  0x4e,
+  0x327,
+  0x6e,
+  0x327,
+  0x4e,
+  0x30c,
+  0x6e,
+  0x30c,
+  0x2bc,
+  0x6e,
+  0x4f,
+  0x304,
+  0x6f,
+  0x304,
+  0x4f,
+  0x306,
+  0x6f,
+  0x306,
+  0x4f,
+  0x30b,
+  0x6f,
+  0x30b,
+  0x52,
+  0x301,
+  0x72,
+  0x301,
+  0x52,
+  0x327,
+  0x72,
+  0x327,
+  0x52,
+  0x30c,
+  0x72,
+  0x30c,
+  0x53,
+  0x301,
+  0x73,
+  0x301,
+  0x53,
+  0x302,
+  0x73,
+  0x302,
+  0x53,
+  0x327,
+  0x73,
+  0x327,
+  0x53,
+  0x30c,
+  0x73,
+  0x30c,
+  0x54,
+  0x327,
+  0x74,
+  0x327,
+  0x54,
+  0x30c,
+  0x74,
+  0x30c,
+  0x55,
+  0x303,
+  0x75,
+  0x303,
+  0x55,
+  0x304,
+  0x75,
+  0x304,
+  0x55,
+  0x306,
+  0x75,
+  0x306,
+  0x55,
+  0x30a,
+  0x75,
+  0x30a,
+  0x55,
+  0x30b,
+  0x75,
+  0x30b,
+  0x55,
+  0x328,
+  0x75,
+  0x328,
+  0x57,
+  0x302,
+  0x77,
+  0x302,
+  0x59,
+  0x302,
+  0x79,
+  0x302,
+  0x59,
+  0x308,
+  0x5a,
+  0x301,
+  0x7a,
+  0x301,
+  0x5a,
+  0x307,
+  0x7a,
+  0x307,
+  0x5a,
+  0x30c,
+  0x7a,
+  0x30c,
+  0x4f,
+  0x31b,
+  0x6f,
+  0x31b,
+  0x55,
+  0x31b,
+  0x75,
+  0x31b,
+  0x44,
+  0x17d,
+  0x44,
+  0x17e,
+  0x64,
+  0x17e,
+  0x4c,
+  0x4a,
+  0x4c,
+  0x6a,
+  0x6c,
+  0x6a,
+  0x4e,
+  0x4a,
+  0x4e,
+  0x6a,
+  0x6e,
+  0x6a,
+  0x41,
+  0x30c,
+  0x61,
+  0x30c,
+  0x49,
+  0x30c,
+  0x69,
+  0x30c,
+  0x4f,
+  0x30c,
+  0x6f,
+  0x30c,
+  0x55,
+  0x30c,
+  0x75,
+  0x30c,
+  0xdc,
+  0x304,
+  0xfc,
+  0x304,
+  0xdc,
+  0x301,
+  0xfc,
+  0x301,
+  0xdc,
+  0x30c,
+  0xfc,
+  0x30c,
+  0xdc,
+  0x300,
+  0xfc,
+  0x300,
+  0xc4,
+  0x304,
+  0xe4,
+  0x304,
+  0x226,
+  0x304,
+  0x227,
+  0x304,
+  0xc6,
+  0x304,
+  0xe6,
+  0x304,
+  0x47,
+  0x30c,
+  0x67,
+  0x30c,
+  0x4b,
+  0x30c,
+  0x6b,
+  0x30c,
+  0x4f,
+  0x328,
+  0x6f,
+  0x328,
+  0x1ea,
+  0x304,
+  0x1eb,
+  0x304,
+  0x1b7,
+  0x30c,
+  0x292,
+  0x30c,
+  0x6a,
+  0x30c,
+  0x44,
+  0x5a,
+  0x44,
+  0x7a,
+  0x64,
+  0x7a,
+  0x47,
+  0x301,
+  0x67,
+  0x301,
+  0x4e,
+  0x300,
+  0x6e,
+  0x300,
+  0xc5,
+  0x301,
+  0xe5,
+  0x301,
+  0xc6,
+  0x301,
+  0xe6,
+  0x301,
+  0xd8,
+  0x301,
+  0xf8,
+  0x301,
+  0x41,
+  0x30f,
+  0x61,
+  0x30f,
+  0x41,
+  0x311,
+  0x61,
+  0x311,
+  0x45,
+  0x30f,
+  0x65,
+  0x30f,
+  0x45,
+  0x311,
+  0x65,
+  0x311,
+  0x49,
+  0x30f,
+  0x69,
+  0x30f,
+  0x49,
+  0x311,
+  0x69,
+  0x311,
+  0x4f,
+  0x30f,
+  0x6f,
+  0x30f,
+  0x4f,
+  0x311,
+  0x6f,
+  0x311,
+  0x52,
+  0x30f,
+  0x72,
+  0x30f,
+  0x52,
+  0x311,
+  0x72,
+  0x311,
+  0x55,
+  0x30f,
+  0x75,
+  0x30f,
+  0x55,
+  0x311,
+  0x75,
+  0x311,
+  0x53,
+  0x326,
+  0x73,
+  0x326,
+  0x54,
+  0x326,
+  0x74,
+  0x326,
+  0x48,
+  0x30c,
+  0x68,
+  0x30c,
+  0x41,
+  0x307,
+  0x61,
+  0x307,
+  0x45,
+  0x327,
+  0x65,
+  0x327,
+  0xd6,
+  0x304,
+  0xf6,
+  0x304,
+  0xd5,
+  0x304,
+  0xf5,
+  0x304,
+  0x4f,
+  0x307,
+  0x6f,
+  0x307,
+  0x22e,
+  0x304,
+  0x22f,
+  0x304,
+  0x59,
+  0x304,
+  0x79,
+  0x304,
+  0x266,
+  0x279,
+  0x27b,
+  0x281,
+  0x20,
+  0x306,
+  0x20,
+  0x307,
+  0x20,
+  0x30a,
+  0x20,
+  0x328,
+  0x20,
+  0x303,
+  0x20,
+  0x30b,
+  0x263,
+  0x78,
+  0x295,
+  0x313,
+  0x308,
+  0x301,
+  0x2b9,
+  0x20,
+  0x345,
+  0x3b,
+  0xa8,
+  0x301,
+  0x391,
+  0x301,
+  0x395,
+  0x301,
+  0x397,
+  0x301,
+  0x399,
+  0x301,
+  0x39f,
+  0x301,
+  0x3a5,
+  0x301,
+  0x3a9,
+  0x301,
+  0x3ca,
+  0x301,
+  0x399,
+  0x308,
+  0x3a5,
+  0x308,
+  0x3b1,
+  0x301,
+  0x3b5,
+  0x301,
+  0x3b7,
+  0x301,
+  0x3b9,
+  0x301,
+  0x3cb,
+  0x301,
+  0x3b9,
+  0x308,
+  0x3c5,
+  0x308,
+  0x3bf,
+  0x301,
+  0x3c5,
+  0x301,
+  0x3c9,
+  0x301,
+  0x3b2,
+  0x3b8,
+  0x3d2,
+  0x301,
+  0x3d2,
+  0x308,
+  0x3c6,
+  0x3c0,
+  0x3ba,
+  0x3c1,
+  0x3c2,
+  0x398,
+  0x3a3,
+  0x415,
+  0x300,
+  0x415,
+  0x308,
+  0x413,
+  0x301,
+  0x406,
+  0x308,
+  0x41a,
+  0x301,
+  0x418,
+  0x300,
+  0x423,
+  0x306,
+  0x418,
+  0x306,
+  0x438,
+  0x306,
+  0x435,
+  0x300,
+  0x435,
+  0x308,
+  0x433,
+  0x301,
+  0x456,
+  0x308,
+  0x43a,
+  0x301,
+  0x438,
+  0x300,
+  0x443,
+  0x306,
+  0x474,
+  0x30f,
+  0x475,
+  0x30f,
+  0x416,
+  0x306,
+  0x436,
+  0x306,
+  0x410,
+  0x306,
+  0x430,
+  0x306,
+  0x410,
+  0x308,
+  0x430,
+  0x308,
+  0x415,
+  0x306,
+  0x435,
+  0x306,
+  0x4d8,
+  0x308,
+  0x4d9,
+  0x308,
+  0x416,
+  0x308,
+  0x436,
+  0x308,
+  0x417,
+  0x308,
+  0x437,
+  0x308,
+  0x418,
+  0x304,
+  0x438,
+  0x304,
+  0x418,
+  0x308,
+  0x438,
+  0x308,
+  0x41e,
+  0x308,
+  0x43e,
+  0x308,
+  0x4e8,
+  0x308,
+  0x4e9,
+  0x308,
+  0x42d,
+  0x308,
+  0x44d,
+  0x308,
+  0x423,
+  0x304,
+  0x443,
+  0x304,
+  0x423,
+  0x308,
+  0x443,
+  0x308,
+  0x423,
+  0x30b,
+  0x443,
+  0x30b,
+  0x427,
+  0x308,
+  0x447,
+  0x308,
+  0x42b,
+  0x308,
+  0x44b,
+  0x308,
+  0x565,
+  0x582,
+  0x627,
+  0x653,
+  0x627,
+  0x654,
+  0x648,
+  0x654,
+  0x627,
+  0x655,
+  0x64a,
+  0x654,
+  0x627,
+  0x674,
+  0x648,
+  0x674,
+  0x6c7,
+  0x674,
+  0x64a,
+  0x674,
+  0x6d5,
+  0x654,
+  0x6c1,
+  0x654,
+  0x6d2,
+  0x654,
+  0x928,
+  0x93c,
+  0x930,
+  0x93c,
+  0x933,
+  0x93c,
+  0x915,
+  0x93c,
+  0x916,
+  0x93c,
+  0x917,
+  0x93c,
+  0x91c,
+  0x93c,
+  0x921,
+  0x93c,
+  0x922,
+  0x93c,
+  0x92b,
+  0x93c,
+  0x92f,
+  0x93c,
+  0x9c7,
+  0x9be,
+  0x9c7,
+  0x9d7,
+  0x9a1,
+  0x9bc,
+  0x9a2,
+  0x9bc,
+  0x9af,
+  0x9bc,
+  0xa32,
+  0xa3c,
+  0xa38,
+  0xa3c,
+  0xa16,
+  0xa3c,
+  0xa17,
+  0xa3c,
+  0xa1c,
+  0xa3c,
+  0xa2b,
+  0xa3c,
+  0xb47,
+  0xb56,
+  0xb47,
+  0xb3e,
+  0xb47,
+  0xb57,
+  0xb21,
+  0xb3c,
+  0xb22,
+  0xb3c,
+  0xb92,
+  0xbd7,
+  0xbc6,
+  0xbbe,
+  0xbc7,
+  0xbbe,
+  0xbc6,
+  0xbd7,
+  0xc46,
+  0xc56,
+  0xcbf,
+  0xcd5,
+  0xcc6,
+  0xcd5,
+  0xcc6,
+  0xcd6,
+  0xcc6,
+  0xcc2,
+  0xcca,
+  0xcd5,
+  0xd46,
+  0xd3e,
+  0xd47,
+  0xd3e,
+  0xd46,
+  0xd57,
+  0xdd9,
+  0xdca,
+  0xdd9,
+  0xdcf,
+  0xddc,
+  0xdca,
+  0xdd9,
+  0xddf,
+  0xe4d,
+  0xe32,
+  0xecd,
+  0xeb2,
+  0xeab,
+  0xe99,
+  0xeab,
+  0xea1,
+  0xf0b,
+  0xf42,
+  0xfb7,
+  0xf4c,
+  0xfb7,
+  0xf51,
+  0xfb7,
+  0xf56,
+  0xfb7,
+  0xf5b,
+  0xfb7,
+  0xf40,
+  0xfb5,
+  0xf71,
+  0xf72,
+  0xf71,
+  0xf74,
+  0xfb2,
+  0xf80,
+  0xfb2,
+  0xf81,
+  0xfb3,
+  0xf80,
+  0xfb3,
+  0xf81,
+  0xf71,
+  0xf80,
+  0xf92,
+  0xfb7,
+  0xf9c,
+  0xfb7,
+  0xfa1,
+  0xfb7,
+  0xfa6,
+  0xfb7,
+  0xfab,
+  0xfb7,
+  0xf90,
+  0xfb5,
+  0x1025,
+  0x102e,
+  0x42,
+  0x18e,
+  0x4d,
+  0x222,
+  0x50,
+  0x250,
+  0x251,
+  0x1d02,
+  0x62,
+  0x259,
+  0x25b,
+  0x25c,
+  0x6d,
+  0x14b,
+  0x254,
+  0x1d16,
+  0x1d17,
+  0x70,
+  0x1d1d,
+  0x26f,
+  0x76,
+  0x1d25,
+  0x3b3,
+  0x3b4,
+  0x3c7,
+  0x41,
+  0x325,
+  0x61,
+  0x325,
+  0x42,
+  0x307,
+  0x62,
+  0x307,
+  0x42,
+  0x323,
+  0x62,
+  0x323,
+  0x42,
+  0x331,
+  0x62,
+  0x331,
+  0xc7,
+  0x301,
+  0xe7,
+  0x301,
+  0x44,
+  0x307,
+  0x64,
+  0x307,
+  0x44,
+  0x323,
+  0x64,
+  0x323,
+  0x44,
+  0x331,
+  0x64,
+  0x331,
+  0x44,
+  0x327,
+  0x64,
+  0x327,
+  0x44,
+  0x32d,
+  0x64,
+  0x32d,
+  0x112,
+  0x300,
+  0x113,
+  0x300,
+  0x112,
+  0x301,
+  0x113,
+  0x301,
+  0x45,
+  0x32d,
+  0x65,
+  0x32d,
+  0x45,
+  0x330,
+  0x65,
+  0x330,
+  0x228,
+  0x306,
+  0x229,
+  0x306,
+  0x46,
+  0x307,
+  0x66,
+  0x307,
+  0x47,
+  0x304,
+  0x67,
+  0x304,
+  0x48,
+  0x307,
+  0x68,
+  0x307,
+  0x48,
+  0x323,
+  0x68,
+  0x323,
+  0x48,
+  0x308,
+  0x68,
+  0x308,
+  0x48,
+  0x327,
+  0x68,
+  0x327,
+  0x48,
+  0x32e,
+  0x68,
+  0x32e,
+  0x49,
+  0x330,
+  0x69,
+  0x330,
+  0xcf,
+  0x301,
+  0xef,
+  0x301,
+  0x4b,
+  0x301,
+  0x6b,
+  0x301,
+  0x4b,
+  0x323,
+  0x6b,
+  0x323,
+  0x4b,
+  0x331,
+  0x6b,
+  0x331,
+  0x4c,
+  0x323,
+  0x6c,
+  0x323,
+  0x1e36,
+  0x304,
+  0x1e37,
+  0x304,
+  0x4c,
+  0x331,
+  0x6c,
+  0x331,
+  0x4c,
+  0x32d,
+  0x6c,
+  0x32d,
+  0x4d,
+  0x301,
+  0x6d,
+  0x301,
+  0x4d,
+  0x307,
+  0x6d,
+  0x307,
+  0x4d,
+  0x323,
+  0x6d,
+  0x323,
+  0x4e,
+  0x307,
+  0x6e,
+  0x307,
+  0x4e,
+  0x323,
+  0x6e,
+  0x323,
+  0x4e,
+  0x331,
+  0x6e,
+  0x331,
+  0x4e,
+  0x32d,
+  0x6e,
+  0x32d,
+  0xd5,
+  0x301,
+  0xf5,
+  0x301,
+  0xd5,
+  0x308,
+  0xf5,
+  0x308,
+  0x14c,
+  0x300,
+  0x14d,
+  0x300,
+  0x14c,
+  0x301,
+  0x14d,
+  0x301,
+  0x50,
+  0x301,
+  0x70,
+  0x301,
+  0x50,
+  0x307,
+  0x70,
+  0x307,
+  0x52,
+  0x307,
+  0x72,
+  0x307,
+  0x52,
+  0x323,
+  0x72,
+  0x323,
+  0x1e5a,
+  0x304,
+  0x1e5b,
+  0x304,
+  0x52,
+  0x331,
+  0x72,
+  0x331,
+  0x53,
+  0x307,
+  0x73,
+  0x307,
+  0x53,
+  0x323,
+  0x73,
+  0x323,
+  0x15a,
+  0x307,
+  0x15b,
+  0x307,
+  0x160,
+  0x307,
+  0x161,
+  0x307,
+  0x1e62,
+  0x307,
+  0x1e63,
+  0x307,
+  0x54,
+  0x307,
+  0x74,
+  0x307,
+  0x54,
+  0x323,
+  0x74,
+  0x323,
+  0x54,
+  0x331,
+  0x74,
+  0x331,
+  0x54,
+  0x32d,
+  0x74,
+  0x32d,
+  0x55,
+  0x324,
+  0x75,
+  0x324,
+  0x55,
+  0x330,
+  0x75,
+  0x330,
+  0x55,
+  0x32d,
+  0x75,
+  0x32d,
+  0x168,
+  0x301,
+  0x169,
+  0x301,
+  0x16a,
+  0x308,
+  0x16b,
+  0x308,
+  0x56,
+  0x303,
+  0x76,
+  0x303,
+  0x56,
+  0x323,
+  0x76,
+  0x323,
+  0x57,
+  0x300,
+  0x77,
+  0x300,
+  0x57,
+  0x301,
+  0x77,
+  0x301,
+  0x57,
+  0x308,
+  0x77,
+  0x308,
+  0x57,
+  0x307,
+  0x77,
+  0x307,
+  0x57,
+  0x323,
+  0x77,
+  0x323,
+  0x58,
+  0x307,
+  0x78,
+  0x307,
+  0x58,
+  0x308,
+  0x78,
+  0x308,
+  0x59,
+  0x307,
+  0x79,
+  0x307,
+  0x5a,
+  0x302,
+  0x7a,
+  0x302,
+  0x5a,
+  0x323,
+  0x7a,
+  0x323,
+  0x5a,
+  0x331,
+  0x7a,
+  0x331,
+  0x68,
+  0x331,
+  0x74,
+  0x308,
+  0x77,
+  0x30a,
+  0x79,
+  0x30a,
+  0x61,
+  0x2be,
+  0x17f,
+  0x307,
+  0x41,
+  0x323,
+  0x61,
+  0x323,
+  0x41,
+  0x309,
+  0x61,
+  0x309,
+  0xc2,
+  0x301,
+  0xe2,
+  0x301,
+  0xc2,
+  0x300,
+  0xe2,
+  0x300,
+  0xc2,
+  0x309,
+  0xe2,
+  0x309,
+  0xc2,
+  0x303,
+  0xe2,
+  0x303,
+  0x1ea0,
+  0x302,
+  0x1ea1,
+  0x302,
+  0x102,
+  0x301,
+  0x103,
+  0x301,
+  0x102,
+  0x300,
+  0x103,
+  0x300,
+  0x102,
+  0x309,
+  0x103,
+  0x309,
+  0x102,
+  0x303,
+  0x103,
+  0x303,
+  0x1ea0,
+  0x306,
+  0x1ea1,
+  0x306,
+  0x45,
+  0x323,
+  0x65,
+  0x323,
+  0x45,
+  0x309,
+  0x65,
+  0x309,
+  0x45,
+  0x303,
+  0x65,
+  0x303,
+  0xca,
+  0x301,
+  0xea,
+  0x301,
+  0xca,
+  0x300,
+  0xea,
+  0x300,
+  0xca,
+  0x309,
+  0xea,
+  0x309,
+  0xca,
+  0x303,
+  0xea,
+  0x303,
+  0x1eb8,
+  0x302,
+  0x1eb9,
+  0x302,
+  0x49,
+  0x309,
+  0x69,
+  0x309,
+  0x49,
+  0x323,
+  0x69,
+  0x323,
+  0x4f,
+  0x323,
+  0x6f,
+  0x323,
+  0x4f,
+  0x309,
+  0x6f,
+  0x309,
+  0xd4,
+  0x301,
+  0xf4,
+  0x301,
+  0xd4,
+  0x300,
+  0xf4,
+  0x300,
+  0xd4,
+  0x309,
+  0xf4,
+  0x309,
+  0xd4,
+  0x303,
+  0xf4,
+  0x303,
+  0x1ecc,
+  0x302,
+  0x1ecd,
+  0x302,
+  0x1a0,
+  0x301,
+  0x1a1,
+  0x301,
+  0x1a0,
+  0x300,
+  0x1a1,
+  0x300,
+  0x1a0,
+  0x309,
+  0x1a1,
+  0x309,
+  0x1a0,
+  0x303,
+  0x1a1,
+  0x303,
+  0x1a0,
+  0x323,
+  0x1a1,
+  0x323,
+  0x55,
+  0x323,
+  0x75,
+  0x323,
+  0x55,
+  0x309,
+  0x75,
+  0x309,
+  0x1af,
+  0x301,
+  0x1b0,
+  0x301,
+  0x1af,
+  0x300,
+  0x1b0,
+  0x300,
+  0x1af,
+  0x309,
+  0x1b0,
+  0x309,
+  0x1af,
+  0x303,
+  0x1b0,
+  0x303,
+  0x1af,
+  0x323,
+  0x1b0,
+  0x323,
+  0x59,
+  0x300,
+  0x79,
+  0x300,
+  0x59,
+  0x323,
+  0x79,
+  0x323,
+  0x59,
+  0x309,
+  0x79,
+  0x309,
+  0x59,
+  0x303,
+  0x79,
+  0x303,
+  0x3b1,
+  0x313,
+  0x3b1,
+  0x314,
+  0x1f00,
+  0x300,
+  0x1f01,
+  0x300,
+  0x1f00,
+  0x301,
+  0x1f01,
+  0x301,
+  0x1f00,
+  0x342,
+  0x1f01,
+  0x342,
+  0x391,
+  0x313,
+  0x391,
+  0x314,
+  0x1f08,
+  0x300,
+  0x1f09,
+  0x300,
+  0x1f08,
+  0x301,
+  0x1f09,
+  0x301,
+  0x1f08,
+  0x342,
+  0x1f09,
+  0x342,
+  0x3b5,
+  0x313,
+  0x3b5,
+  0x314,
+  0x1f10,
+  0x300,
+  0x1f11,
+  0x300,
+  0x1f10,
+  0x301,
+  0x1f11,
+  0x301,
+  0x395,
+  0x313,
+  0x395,
+  0x314,
+  0x1f18,
+  0x300,
+  0x1f19,
+  0x300,
+  0x1f18,
+  0x301,
+  0x1f19,
+  0x301,
+  0x3b7,
+  0x313,
+  0x3b7,
+  0x314,
+  0x1f20,
+  0x300,
+  0x1f21,
+  0x300,
+  0x1f20,
+  0x301,
+  0x1f21,
+  0x301,
+  0x1f20,
+  0x342,
+  0x1f21,
+  0x342,
+  0x397,
+  0x313,
+  0x397,
+  0x314,
+  0x1f28,
+  0x300,
+  0x1f29,
+  0x300,
+  0x1f28,
+  0x301,
+  0x1f29,
+  0x301,
+  0x1f28,
+  0x342,
+  0x1f29,
+  0x342,
+  0x3b9,
+  0x313,
+  0x3b9,
+  0x314,
+  0x1f30,
+  0x300,
+  0x1f31,
+  0x300,
+  0x1f30,
+  0x301,
+  0x1f31,
+  0x301,
+  0x1f30,
+  0x342,
+  0x1f31,
+  0x342,
+  0x399,
+  0x313,
+  0x399,
+  0x314,
+  0x1f38,
+  0x300,
+  0x1f39,
+  0x300,
+  0x1f38,
+  0x301,
+  0x1f39,
+  0x301,
+  0x1f38,
+  0x342,
+  0x1f39,
+  0x342,
+  0x3bf,
+  0x313,
+  0x3bf,
+  0x314,
+  0x1f40,
+  0x300,
+  0x1f41,
+  0x300,
+  0x1f40,
+  0x301,
+  0x1f41,
+  0x301,
+  0x39f,
+  0x313,
+  0x39f,
+  0x314,
+  0x1f48,
+  0x300,
+  0x1f49,
+  0x300,
+  0x1f48,
+  0x301,
+  0x1f49,
+  0x301,
+  0x3c5,
+  0x313,
+  0x3c5,
+  0x314,
+  0x1f50,
+  0x300,
+  0x1f51,
+  0x300,
+  0x1f50,
+  0x301,
+  0x1f51,
+  0x301,
+  0x1f50,
+  0x342,
+  0x1f51,
+  0x342,
+  0x3a5,
+  0x314,
+  0x1f59,
+  0x300,
+  0x1f59,
+  0x301,
+  0x1f59,
+  0x342,
+  0x3c9,
+  0x313,
+  0x3c9,
+  0x314,
+  0x1f60,
+  0x300,
+  0x1f61,
+  0x300,
+  0x1f60,
+  0x301,
+  0x1f61,
+  0x301,
+  0x1f60,
+  0x342,
+  0x1f61,
+  0x342,
+  0x3a9,
+  0x313,
+  0x3a9,
+  0x314,
+  0x1f68,
+  0x300,
+  0x1f69,
+  0x300,
+  0x1f68,
+  0x301,
+  0x1f69,
+  0x301,
+  0x1f68,
+  0x342,
+  0x1f69,
+  0x342,
+  0x3b1,
+  0x300,
+  0x3ac,
+  0x3b5,
+  0x300,
+  0x3ad,
+  0x3b7,
+  0x300,
+  0x3ae,
+  0x3b9,
+  0x300,
+  0x3af,
+  0x3bf,
+  0x300,
+  0x3cc,
+  0x3c5,
+  0x300,
+  0x3cd,
+  0x3c9,
+  0x300,
+  0x3ce,
+  0x1f00,
+  0x345,
+  0x1f01,
+  0x345,
+  0x1f02,
+  0x345,
+  0x1f03,
+  0x345,
+  0x1f04,
+  0x345,
+  0x1f05,
+  0x345,
+  0x1f06,
+  0x345,
+  0x1f07,
+  0x345,
+  0x1f08,
+  0x345,
+  0x1f09,
+  0x345,
+  0x1f0a,
+  0x345,
+  0x1f0b,
+  0x345,
+  0x1f0c,
+  0x345,
+  0x1f0d,
+  0x345,
+  0x1f0e,
+  0x345,
+  0x1f0f,
+  0x345,
+  0x1f20,
+  0x345,
+  0x1f21,
+  0x345,
+  0x1f22,
+  0x345,
+  0x1f23,
+  0x345,
+  0x1f24,
+  0x345,
+  0x1f25,
+  0x345,
+  0x1f26,
+  0x345,
+  0x1f27,
+  0x345,
+  0x1f28,
+  0x345,
+  0x1f29,
+  0x345,
+  0x1f2a,
+  0x345,
+  0x1f2b,
+  0x345,
+  0x1f2c,
+  0x345,
+  0x1f2d,
+  0x345,
+  0x1f2e,
+  0x345,
+  0x1f2f,
+  0x345,
+  0x1f60,
+  0x345,
+  0x1f61,
+  0x345,
+  0x1f62,
+  0x345,
+  0x1f63,
+  0x345,
+  0x1f64,
+  0x345,
+  0x1f65,
+  0x345,
+  0x1f66,
+  0x345,
+  0x1f67,
+  0x345,
+  0x1f68,
+  0x345,
+  0x1f69,
+  0x345,
+  0x1f6a,
+  0x345,
+  0x1f6b,
+  0x345,
+  0x1f6c,
+  0x345,
+  0x1f6d,
+  0x345,
+  0x1f6e,
+  0x345,
+  0x1f6f,
+  0x345,
+  0x3b1,
+  0x306,
+  0x3b1,
+  0x304,
+  0x1f70,
+  0x345,
+  0x3b1,
+  0x345,
+  0x3ac,
+  0x345,
+  0x3b1,
+  0x342,
+  0x1fb6,
+  0x345,
+  0x391,
+  0x306,
+  0x391,
+  0x304,
+  0x391,
+  0x300,
+  0x386,
+  0x391,
+  0x345,
+  0x20,
+  0x313,
+  0x20,
+  0x342,
+  0xa8,
+  0x342,
+  0x1f74,
+  0x345,
+  0x3b7,
+  0x345,
+  0x3ae,
+  0x345,
+  0x3b7,
+  0x342,
+  0x1fc6,
+  0x345,
+  0x395,
+  0x300,
+  0x388,
+  0x397,
+  0x300,
+  0x389,
+  0x397,
+  0x345,
+  0x1fbf,
+  0x300,
+  0x1fbf,
+  0x301,
+  0x1fbf,
+  0x342,
+  0x3b9,
+  0x306,
+  0x3b9,
+  0x304,
+  0x3ca,
+  0x300,
+  0x390,
+  0x3b9,
+  0x342,
+  0x3ca,
+  0x342,
+  0x399,
+  0x306,
+  0x399,
+  0x304,
+  0x399,
+  0x300,
+  0x38a,
+  0x1ffe,
+  0x300,
+  0x1ffe,
+  0x301,
+  0x1ffe,
+  0x342,
+  0x3c5,
+  0x306,
+  0x3c5,
+  0x304,
+  0x3cb,
+  0x300,
+  0x3b0,
+  0x3c1,
+  0x313,
+  0x3c1,
+  0x314,
+  0x3c5,
+  0x342,
+  0x3cb,
+  0x342,
+  0x3a5,
+  0x306,
+  0x3a5,
+  0x304,
+  0x3a5,
+  0x300,
+  0x38e,
+  0x3a1,
+  0x314,
+  0xa8,
+  0x300,
+  0x385,
+  0x60,
+  0x1f7c,
+  0x345,
+  0x3c9,
+  0x345,
+  0x3ce,
+  0x345,
+  0x3c9,
+  0x342,
+  0x1ff6,
+  0x345,
+  0x39f,
+  0x300,
+  0x38c,
+  0x3a9,
+  0x300,
+  0x38f,
+  0x3a9,
+  0x345,
+  0xb4,
+  0x20,
+  0x314,
+  0x2002,
+  0x2003,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x20,
+  0x2010,
+  0x20,
+  0x333,
+  0x2e,
+  0x2e,
+  0x2e,
+  0x20,
+  0x2032,
+  0x2032,
+  0x2032,
+  0x2032,
+  0x2032,
+  0x2035,
+  0x2035,
+  0x2035,
+  0x2035,
+  0x2035,
+  0x21,
+  0x21,
+  0x20,
+  0x305,
+  0x3f,
+  0x3f,
+  0x3f,
+  0x21,
+  0x21,
+  0x3f,
+  0x20,
+  0x30,
+  0x35,
+  0x36,
+  0x37,
+  0x38,
+  0x39,
+  0x2b,
+  0x2212,
+  0x3d,
+  0x28,
+  0x29,
+  0x52,
+  0x73,
+  0x61,
+  0x2f,
+  0x63,
+  0x61,
+  0x2f,
+  0x73,
+  0xb0,
+  0x43,
+  0x63,
+  0x2f,
+  0x6f,
+  0x63,
+  0x2f,
+  0x75,
+  0x190,
+  0xb0,
+  0x46,
+  0x127,
+  0x4e,
+  0x6f,
+  0x51,
+  0x53,
+  0x4d,
+  0x54,
+  0x45,
+  0x4c,
+  0x54,
+  0x4d,
+  0x5d0,
+  0x5d1,
+  0x5d2,
+  0x5d3,
+  0x46,
+  0x41,
+  0x58,
+  0x393,
+  0x3a0,
+  0x2211,
+  0x31,
+  0x2044,
+  0x33,
+  0x32,
+  0x2044,
+  0x33,
+  0x31,
+  0x2044,
+  0x35,
+  0x32,
+  0x2044,
+  0x35,
+  0x33,
+  0x2044,
+  0x35,
+  0x34,
+  0x2044,
+  0x35,
+  0x31,
+  0x2044,
+  0x36,
+  0x35,
+  0x2044,
+  0x36,
+  0x31,
+  0x2044,
+  0x38,
+  0x33,
+  0x2044,
+  0x38,
+  0x35,
+  0x2044,
+  0x38,
+  0x37,
+  0x2044,
+  0x38,
+  0x49,
+  0x49,
+  0x49,
+  0x49,
+  0x49,
+  0x49,
+  0x56,
+  0x56,
+  0x49,
+  0x56,
+  0x49,
+  0x49,
+  0x56,
+  0x49,
+  0x49,
+  0x49,
+  0x49,
+  0x58,
+  0x58,
+  0x49,
+  0x58,
+  0x49,
+  0x49,
+  0x69,
+  0x69,
+  0x69,
+  0x69,
+  0x69,
+  0x69,
+  0x76,
+  0x76,
+  0x69,
+  0x76,
+  0x69,
+  0x69,
+  0x76,
+  0x69,
+  0x69,
+  0x69,
+  0x69,
+  0x78,
+  0x78,
+  0x69,
+  0x78,
+  0x69,
+  0x69,
+  0x2190,
+  0x338,
+  0x2192,
+  0x338,
+  0x2194,
+  0x338,
+  0x21d0,
+  0x338,
+  0x21d4,
+  0x338,
+  0x21d2,
+  0x338,
+  0x2203,
+  0x338,
+  0x2208,
+  0x338,
+  0x220b,
+  0x338,
+  0x2223,
+  0x338,
+  0x2225,
+  0x338,
+  0x222b,
+  0x222b,
+  0x222b,
+  0x222b,
+  0x222b,
+  0x222e,
+  0x222e,
+  0x222e,
+  0x222e,
+  0x222e,
+  0x223c,
+  0x338,
+  0x2243,
+  0x338,
+  0x2245,
+  0x338,
+  0x2248,
+  0x338,
+  0x3d,
+  0x338,
+  0x2261,
+  0x338,
+  0x224d,
+  0x338,
+  0x3c,
+  0x338,
+  0x3e,
+  0x338,
+  0x2264,
+  0x338,
+  0x2265,
+  0x338,
+  0x2272,
+  0x338,
+  0x2273,
+  0x338,
+  0x2276,
+  0x338,
+  0x2277,
+  0x338,
+  0x227a,
+  0x338,
+  0x227b,
+  0x338,
+  0x2282,
+  0x338,
+  0x2283,
+  0x338,
+  0x2286,
+  0x338,
+  0x2287,
+  0x338,
+  0x22a2,
+  0x338,
+  0x22a8,
+  0x338,
+  0x22a9,
+  0x338,
+  0x22ab,
+  0x338,
+  0x227c,
+  0x338,
+  0x227d,
+  0x338,
+  0x2291,
+  0x338,
+  0x2292,
+  0x338,
+  0x22b2,
+  0x338,
+  0x22b3,
+  0x338,
+  0x22b4,
+  0x338,
+  0x22b5,
+  0x338,
+  0x3008,
+  0x3009,
+  0x31,
+  0x30,
+  0x31,
+  0x31,
+  0x31,
+  0x32,
+  0x31,
+  0x33,
+  0x31,
+  0x34,
+  0x31,
+  0x35,
+  0x31,
+  0x36,
+  0x31,
+  0x37,
+  0x31,
+  0x38,
+  0x31,
+  0x39,
+  0x32,
+  0x30,
+  0x28,
+  0x31,
+  0x29,
+  0x28,
+  0x32,
+  0x29,
+  0x28,
+  0x33,
+  0x29,
+  0x28,
+  0x34,
+  0x29,
+  0x28,
+  0x35,
+  0x29,
+  0x28,
+  0x36,
+  0x29,
+  0x28,
+  0x37,
+  0x29,
+  0x28,
+  0x38,
+  0x29,
+  0x28,
+  0x39,
+  0x29,
+  0x28,
+  0x31,
+  0x30,
+  0x29,
+  0x28,
+  0x31,
+  0x31,
+  0x29,
+  0x28,
+  0x31,
+  0x32,
+  0x29,
+  0x28,
+  0x31,
+  0x33,
+  0x29,
+  0x28,
+  0x31,
+  0x34,
+  0x29,
+  0x28,
+  0x31,
+  0x35,
+  0x29,
+  0x28,
+  0x31,
+  0x36,
+  0x29,
+  0x28,
+  0x31,
+  0x37,
+  0x29,
+  0x28,
+  0x31,
+  0x38,
+  0x29,
+  0x28,
+  0x31,
+  0x39,
+  0x29,
+  0x28,
+  0x32,
+  0x30,
+  0x29,
+  0x31,
+  0x2e,
+  0x32,
+  0x2e,
+  0x33,
+  0x2e,
+  0x34,
+  0x2e,
+  0x35,
+  0x2e,
+  0x36,
+  0x2e,
+  0x37,
+  0x2e,
+  0x38,
+  0x2e,
+  0x39,
+  0x2e,
+  0x31,
+  0x30,
+  0x2e,
+  0x31,
+  0x31,
+  0x2e,
+  0x31,
+  0x32,
+  0x2e,
+  0x31,
+  0x33,
+  0x2e,
+  0x31,
+  0x34,
+  0x2e,
+  0x31,
+  0x35,
+  0x2e,
+  0x31,
+  0x36,
+  0x2e,
+  0x31,
+  0x37,
+  0x2e,
+  0x31,
+  0x38,
+  0x2e,
+  0x31,
+  0x39,
+  0x2e,
+  0x32,
+  0x30,
+  0x2e,
+  0x28,
+  0x61,
+  0x29,
+  0x28,
+  0x62,
+  0x29,
+  0x28,
+  0x63,
+  0x29,
+  0x28,
+  0x64,
+  0x29,
+  0x28,
+  0x65,
+  0x29,
+  0x28,
+  0x66,
+  0x29,
+  0x28,
+  0x67,
+  0x29,
+  0x28,
+  0x68,
+  0x29,
+  0x28,
+  0x69,
+  0x29,
+  0x28,
+  0x6a,
+  0x29,
+  0x28,
+  0x6b,
+  0x29,
+  0x28,
+  0x6c,
+  0x29,
+  0x28,
+  0x6d,
+  0x29,
+  0x28,
+  0x6e,
+  0x29,
+  0x28,
+  0x6f,
+  0x29,
+  0x28,
+  0x70,
+  0x29,
+  0x28,
+  0x71,
+  0x29,
+  0x28,
+  0x72,
+  0x29,
+  0x28,
+  0x73,
+  0x29,
+  0x28,
+  0x74,
+  0x29,
+  0x28,
+  0x75,
+  0x29,
+  0x28,
+  0x76,
+  0x29,
+  0x28,
+  0x77,
+  0x29,
+  0x28,
+  0x78,
+  0x29,
+  0x28,
+  0x79,
+  0x29,
+  0x28,
+  0x7a,
+  0x29,
+  0x3a,
+  0x3a,
+  0x3d,
+  0x3d,
+  0x3d,
+  0x2add,
+  0x338,
+  0x6bcd,
+  0x9f9f,
+  0x4e00,
+  0x4e28,
+  0x4e36,
+  0x4e3f,
+  0x4e59,
+  0x4e85,
+  0x4e8c,
+  0x4ea0,
+  0x4eba,
+  0x513f,
+  0x5165,
+  0x516b,
+  0x5182,
+  0x5196,
+  0x51ab,
+  0x51e0,
+  0x51f5,
+  0x5200,
+  0x529b,
+  0x52f9,
+  0x5315,
+  0x531a,
+  0x5338,
+  0x5341,
+  0x535c,
+  0x5369,
+  0x5382,
+  0x53b6,
+  0x53c8,
+  0x53e3,
+  0x56d7,
+  0x571f,
+  0x58eb,
+  0x5902,
+  0x590a,
+  0x5915,
+  0x5927,
+  0x5973,
+  0x5b50,
+  0x5b80,
+  0x5bf8,
+  0x5c0f,
+  0x5c22,
+  0x5c38,
+  0x5c6e,
+  0x5c71,
+  0x5ddb,
+  0x5de5,
+  0x5df1,
+  0x5dfe,
+  0x5e72,
+  0x5e7a,
+  0x5e7f,
+  0x5ef4,
+  0x5efe,
+  0x5f0b,
+  0x5f13,
+  0x5f50,
+  0x5f61,
+  0x5f73,
+  0x5fc3,
+  0x6208,
+  0x6236,
+  0x624b,
+  0x652f,
+  0x6534,
+  0x6587,
+  0x6597,
+  0x65a4,
+  0x65b9,
+  0x65e0,
+  0x65e5,
+  0x66f0,
+  0x6708,
+  0x6728,
+  0x6b20,
+  0x6b62,
+  0x6b79,
+  0x6bb3,
+  0x6bcb,
+  0x6bd4,
+  0x6bdb,
+  0x6c0f,
+  0x6c14,
+  0x6c34,
+  0x706b,
+  0x722a,
+  0x7236,
+  0x723b,
+  0x723f,
+  0x7247,
+  0x7259,
+  0x725b,
+  0x72ac,
+  0x7384,
+  0x7389,
+  0x74dc,
+  0x74e6,
+  0x7518,
+  0x751f,
+  0x7528,
+  0x7530,
+  0x758b,
+  0x7592,
+  0x7676,
+  0x767d,
+  0x76ae,
+  0x76bf,
+  0x76ee,
+  0x77db,
+  0x77e2,
+  0x77f3,
+  0x793a,
+  0x79b8,
+  0x79be,
+  0x7a74,
+  0x7acb,
+  0x7af9,
+  0x7c73,
+  0x7cf8,
+  0x7f36,
+  0x7f51,
+  0x7f8a,
+  0x7fbd,
+  0x8001,
+  0x800c,
+  0x8012,
+  0x8033,
+  0x807f,
+  0x8089,
+  0x81e3,
+  0x81ea,
+  0x81f3,
+  0x81fc,
+  0x820c,
+  0x821b,
+  0x821f,
+  0x826e,
+  0x8272,
+  0x8278,
+  0x864d,
+  0x866b,
+  0x8840,
+  0x884c,
+  0x8863,
+  0x897e,
+  0x898b,
+  0x89d2,
+  0x8a00,
+  0x8c37,
+  0x8c46,
+  0x8c55,
+  0x8c78,
+  0x8c9d,
+  0x8d64,
+  0x8d70,
+  0x8db3,
+  0x8eab,
+  0x8eca,
+  0x8f9b,
+  0x8fb0,
+  0x8fb5,
+  0x9091,
+  0x9149,
+  0x91c6,
+  0x91cc,
+  0x91d1,
+  0x9577,
+  0x9580,
+  0x961c,
+  0x96b6,
+  0x96b9,
+  0x96e8,
+  0x9751,
+  0x975e,
+  0x9762,
+  0x9769,
+  0x97cb,
+  0x97ed,
+  0x97f3,
+  0x9801,
+  0x98a8,
+  0x98db,
+  0x98df,
+  0x9996,
+  0x9999,
+  0x99ac,
+  0x9aa8,
+  0x9ad8,
+  0x9adf,
+  0x9b25,
+  0x9b2f,
+  0x9b32,
+  0x9b3c,
+  0x9b5a,
+  0x9ce5,
+  0x9e75,
+  0x9e7f,
+  0x9ea5,
+  0x9ebb,
+  0x9ec3,
+  0x9ecd,
+  0x9ed1,
+  0x9ef9,
+  0x9efd,
+  0x9f0e,
+  0x9f13,
+  0x9f20,
+  0x9f3b,
+  0x9f4a,
+  0x9f52,
+  0x9f8d,
+  0x9f9c,
+  0x9fa0,
+  0x20,
+  0x3012,
+  0x5344,
+  0x5345,
+  0x304b,
+  0x3099,
+  0x304d,
+  0x3099,
+  0x304f,
+  0x3099,
+  0x3051,
+  0x3099,
+  0x3053,
+  0x3099,
+  0x3055,
+  0x3099,
+  0x3057,
+  0x3099,
+  0x3059,
+  0x3099,
+  0x305b,
+  0x3099,
+  0x305d,
+  0x3099,
+  0x305f,
+  0x3099,
+  0x3061,
+  0x3099,
+  0x3064,
+  0x3099,
+  0x3066,
+  0x3099,
+  0x3068,
+  0x3099,
+  0x306f,
+  0x3099,
+  0x306f,
+  0x309a,
+  0x3072,
+  0x3099,
+  0x3072,
+  0x309a,
+  0x3075,
+  0x3099,
+  0x3075,
+  0x309a,
+  0x3078,
+  0x3099,
+  0x3078,
+  0x309a,
+  0x307b,
+  0x3099,
+  0x307b,
+  0x309a,
+  0x3046,
+  0x3099,
+  0x20,
+  0x3099,
+  0x20,
+  0x309a,
+  0x309d,
+  0x3099,
+  0x3088,
+  0x308a,
+  0x30ab,
+  0x3099,
+  0x30ad,
+  0x3099,
+  0x30af,
+  0x3099,
+  0x30b1,
+  0x3099,
+  0x30b3,
+  0x3099,
+  0x30b5,
+  0x3099,
+  0x30b7,
+  0x3099,
+  0x30b9,
+  0x3099,
+  0x30bb,
+  0x3099,
+  0x30bd,
+  0x3099,
+  0x30bf,
+  0x3099,
+  0x30c1,
+  0x3099,
+  0x30c4,
+  0x3099,
+  0x30c6,
+  0x3099,
+  0x30c8,
+  0x3099,
+  0x30cf,
+  0x3099,
+  0x30cf,
+  0x309a,
+  0x30d2,
+  0x3099,
+  0x30d2,
+  0x309a,
+  0x30d5,
+  0x3099,
+  0x30d5,
+  0x309a,
+  0x30d8,
+  0x3099,
+  0x30d8,
+  0x309a,
+  0x30db,
+  0x3099,
+  0x30db,
+  0x309a,
+  0x30a6,
+  0x3099,
+  0x30ef,
+  0x3099,
+  0x30f0,
+  0x3099,
+  0x30f1,
+  0x3099,
+  0x30f2,
+  0x3099,
+  0x30fd,
+  0x3099,
+  0x30b3,
+  0x30c8,
+  0x1100,
+  0x1101,
+  0x11aa,
+  0x1102,
+  0x11ac,
+  0x11ad,
+  0x1103,
+  0x1104,
+  0x1105,
+  0x11b0,
+  0x11b1,
+  0x11b2,
+  0x11b3,
+  0x11b4,
+  0x11b5,
+  0x111a,
+  0x1106,
+  0x1107,
+  0x1108,
+  0x1121,
+  0x1109,
+  0x110a,
+  0x110b,
+  0x110c,
+  0x110d,
+  0x110e,
+  0x110f,
+  0x1110,
+  0x1111,
+  0x1112,
+  0x1161,
+  0x1162,
+  0x1163,
+  0x1164,
+  0x1165,
+  0x1166,
+  0x1167,
+  0x1168,
+  0x1169,
+  0x116a,
+  0x116b,
+  0x116c,
+  0x116d,
+  0x116e,
+  0x116f,
+  0x1170,
+  0x1171,
+  0x1172,
+  0x1173,
+  0x1174,
+  0x1175,
+  0x1160,
+  0x1114,
+  0x1115,
+  0x11c7,
+  0x11c8,
+  0x11cc,
+  0x11ce,
+  0x11d3,
+  0x11d7,
+  0x11d9,
+  0x111c,
+  0x11dd,
+  0x11df,
+  0x111d,
+  0x111e,
+  0x1120,
+  0x1122,
+  0x1123,
+  0x1127,
+  0x1129,
+  0x112b,
+  0x112c,
+  0x112d,
+  0x112e,
+  0x112f,
+  0x1132,
+  0x1136,
+  0x1140,
+  0x1147,
+  0x114c,
+  0x11f1,
+  0x11f2,
+  0x1157,
+  0x1158,
+  0x1159,
+  0x1184,
+  0x1185,
+  0x1188,
+  0x1191,
+  0x1192,
+  0x1194,
+  0x119e,
+  0x11a1,
+  0x4e09,
+  0x56db,
+  0x4e0a,
+  0x4e2d,
+  0x4e0b,
+  0x7532,
+  0x4e19,
+  0x4e01,
+  0x5929,
+  0x5730,
+  0x28,
+  0x1100,
+  0x29,
+  0x28,
+  0x1102,
+  0x29,
+  0x28,
+  0x1103,
+  0x29,
+  0x28,
+  0x1105,
+  0x29,
+  0x28,
+  0x1106,
+  0x29,
+  0x28,
+  0x1107,
+  0x29,
+  0x28,
+  0x1109,
+  0x29,
+  0x28,
+  0x110b,
+  0x29,
+  0x28,
+  0x110c,
+  0x29,
+  0x28,
+  0x110e,
+  0x29,
+  0x28,
+  0x110f,
+  0x29,
+  0x28,
+  0x1110,
+  0x29,
+  0x28,
+  0x1111,
+  0x29,
+  0x28,
+  0x1112,
+  0x29,
+  0x28,
+  0x1100,
+  0x1161,
+  0x29,
+  0x28,
+  0x1102,
+  0x1161,
+  0x29,
+  0x28,
+  0x1103,
+  0x1161,
+  0x29,
+  0x28,
+  0x1105,
+  0x1161,
+  0x29,
+  0x28,
+  0x1106,
+  0x1161,
+  0x29,
+  0x28,
+  0x1107,
+  0x1161,
+  0x29,
+  0x28,
+  0x1109,
+  0x1161,
+  0x29,
+  0x28,
+  0x110b,
+  0x1161,
+  0x29,
+  0x28,
+  0x110c,
+  0x1161,
+  0x29,
+  0x28,
+  0x110e,
+  0x1161,
+  0x29,
+  0x28,
+  0x110f,
+  0x1161,
+  0x29,
+  0x28,
+  0x1110,
+  0x1161,
+  0x29,
+  0x28,
+  0x1111,
+  0x1161,
+  0x29,
+  0x28,
+  0x1112,
+  0x1161,
+  0x29,
+  0x28,
+  0x110c,
+  0x116e,
+  0x29,
+  0x28,
+  0x110b,
+  0x1169,
+  0x110c,
+  0x1165,
+  0x11ab,
+  0x29,
+  0x28,
+  0x110b,
+  0x1169,
+  0x1112,
+  0x116e,
+  0x29,
+  0x28,
+  0x4e00,
+  0x29,
+  0x28,
+  0x4e8c,
+  0x29,
+  0x28,
+  0x4e09,
+  0x29,
+  0x28,
+  0x56db,
+  0x29,
+  0x28,
+  0x4e94,
+  0x29,
+  0x28,
+  0x516d,
+  0x29,
+  0x28,
+  0x4e03,
+  0x29,
+  0x28,
+  0x516b,
+  0x29,
+  0x28,
+  0x4e5d,
+  0x29,
+  0x28,
+  0x5341,
+  0x29,
+  0x28,
+  0x6708,
+  0x29,
+  0x28,
+  0x706b,
+  0x29,
+  0x28,
+  0x6c34,
+  0x29,
+  0x28,
+  0x6728,
+  0x29,
+  0x28,
+  0x91d1,
+  0x29,
+  0x28,
+  0x571f,
+  0x29,
+  0x28,
+  0x65e5,
+  0x29,
+  0x28,
+  0x682a,
+  0x29,
+  0x28,
+  0x6709,
+  0x29,
+  0x28,
+  0x793e,
+  0x29,
+  0x28,
+  0x540d,
+  0x29,
+  0x28,
+  0x7279,
+  0x29,
+  0x28,
+  0x8ca1,
+  0x29,
+  0x28,
+  0x795d,
+  0x29,
+  0x28,
+  0x52b4,
+  0x29,
+  0x28,
+  0x4ee3,
+  0x29,
+  0x28,
+  0x547c,
+  0x29,
+  0x28,
+  0x5b66,
+  0x29,
+  0x28,
+  0x76e3,
+  0x29,
+  0x28,
+  0x4f01,
+  0x29,
+  0x28,
+  0x8cc7,
+  0x29,
+  0x28,
+  0x5354,
+  0x29,
+  0x28,
+  0x796d,
+  0x29,
+  0x28,
+  0x4f11,
+  0x29,
+  0x28,
+  0x81ea,
+  0x29,
+  0x28,
+  0x81f3,
+  0x29,
+  0x50,
+  0x54,
+  0x45,
+  0x32,
+  0x32,
+  0x32,
+  0x34,
+  0x32,
+  0x35,
+  0x32,
+  0x36,
+  0x32,
+  0x37,
+  0x32,
+  0x38,
+  0x32,
+  0x39,
+  0x33,
+  0x30,
+  0x33,
+  0x33,
+  0x33,
+  0x34,
+  0x33,
+  0x35,
+  0x110e,
+  0x1161,
+  0x11b7,
+  0x1100,
+  0x1169,
+  0x110c,
+  0x116e,
+  0x110b,
+  0x1174,
+  0x79d8,
+  0x7537,
+  0x9069,
+  0x512a,
+  0x5370,
+  0x6ce8,
+  0x9805,
+  0x5199,
+  0x6b63,
+  0x5de6,
+  0x53f3,
+  0x533b,
+  0x5b97,
+  0x591c,
+  0x33,
+  0x36,
+  0x33,
+  0x37,
+  0x33,
+  0x38,
+  0x33,
+  0x39,
+  0x34,
+  0x30,
+  0x34,
+  0x34,
+  0x34,
+  0x35,
+  0x34,
+  0x36,
+  0x34,
+  0x37,
+  0x34,
+  0x38,
+  0x34,
+  0x39,
+  0x35,
+  0x30,
+  0x31,
+  0x6708,
+  0x32,
+  0x6708,
+  0x33,
+  0x6708,
+  0x34,
+  0x6708,
+  0x35,
+  0x6708,
+  0x36,
+  0x6708,
+  0x37,
+  0x6708,
+  0x38,
+  0x6708,
+  0x39,
+  0x6708,
+  0x31,
+  0x30,
+  0x6708,
+  0x31,
+  0x31,
+  0x6708,
+  0x31,
+  0x32,
+  0x6708,
+  0x48,
+  0x67,
+  0x65,
+  0x72,
+  0x67,
+  0x65,
+  0x56,
+  0x4c,
+  0x54,
+  0x44,
+  0x30a2,
+  0x30a4,
+  0x30a8,
+  0x30aa,
+  0x30ca,
+  0x30cb,
+  0x30cc,
+  0x30cd,
+  0x30ce,
+  0x30de,
+  0x30df,
+  0x30e0,
+  0x30e1,
+  0x30e2,
+  0x30e4,
+  0x30e6,
+  0x30e8,
+  0x30e9,
+  0x30ea,
+  0x30eb,
+  0x30ec,
+  0x30ed,
+  0x30a2,
+  0x30d1,
+  0x30fc,
+  0x30c8,
+  0x30a2,
+  0x30eb,
+  0x30d5,
+  0x30a1,
+  0x30a2,
+  0x30f3,
+  0x30da,
+  0x30a2,
+  0x30a2,
+  0x30fc,
+  0x30eb,
+  0x30a4,
+  0x30cb,
+  0x30f3,
+  0x30b0,
+  0x30a4,
+  0x30f3,
+  0x30c1,
+  0x30a6,
+  0x30a9,
+  0x30f3,
+  0x30a8,
+  0x30b9,
+  0x30af,
+  0x30fc,
+  0x30c9,
+  0x30a8,
+  0x30fc,
+  0x30ab,
+  0x30fc,
+  0x30aa,
+  0x30f3,
+  0x30b9,
+  0x30aa,
+  0x30fc,
+  0x30e0,
+  0x30ab,
+  0x30a4,
+  0x30ea,
+  0x30ab,
+  0x30e9,
+  0x30c3,
+  0x30c8,
+  0x30ab,
+  0x30ed,
+  0x30ea,
+  0x30fc,
+  0x30ac,
+  0x30ed,
+  0x30f3,
+  0x30ac,
+  0x30f3,
+  0x30de,
+  0x30ae,
+  0x30ac,
+  0x30ae,
+  0x30cb,
+  0x30fc,
+  0x30ad,
+  0x30e5,
+  0x30ea,
+  0x30fc,
+  0x30ae,
+  0x30eb,
+  0x30c0,
+  0x30fc,
+  0x30ad,
+  0x30ed,
+  0x30ad,
+  0x30ed,
+  0x30b0,
+  0x30e9,
+  0x30e0,
+  0x30ad,
+  0x30ed,
+  0x30e1,
+  0x30fc,
+  0x30c8,
+  0x30eb,
+  0x30ad,
+  0x30ed,
+  0x30ef,
+  0x30c3,
+  0x30c8,
+  0x30b0,
+  0x30e9,
+  0x30e0,
+  0x30c8,
+  0x30f3,
+  0x30af,
+  0x30eb,
+  0x30bc,
+  0x30a4,
+  0x30ed,
+  0x30af,
+  0x30ed,
+  0x30fc,
+  0x30cd,
+  0x30b1,
+  0x30fc,
+  0x30b9,
+  0x30b3,
+  0x30eb,
+  0x30ca,
+  0x30b3,
+  0x30fc,
+  0x30dd,
+  0x30b5,
+  0x30a4,
+  0x30af,
+  0x30eb,
+  0x30b5,
+  0x30f3,
+  0x30c1,
+  0x30fc,
+  0x30e0,
+  0x30b7,
+  0x30ea,
+  0x30f3,
+  0x30b0,
+  0x30bb,
+  0x30f3,
+  0x30c1,
+  0x30bb,
+  0x30f3,
+  0x30c8,
+  0x30c0,
+  0x30fc,
+  0x30b9,
+  0x30c7,
+  0x30b7,
+  0x30c9,
+  0x30eb,
+  0x30ca,
+  0x30ce,
+  0x30ce,
+  0x30c3,
+  0x30c8,
+  0x30cf,
+  0x30a4,
+  0x30c4,
+  0x30d1,
+  0x30fc,
+  0x30bb,
+  0x30f3,
+  0x30c8,
+  0x30d1,
+  0x30fc,
+  0x30c4,
+  0x30d0,
+  0x30fc,
+  0x30ec,
+  0x30eb,
+  0x30d4,
+  0x30a2,
+  0x30b9,
+  0x30c8,
+  0x30eb,
+  0x30d4,
+  0x30af,
+  0x30eb,
+  0x30d4,
+  0x30b3,
+  0x30d3,
+  0x30eb,
+  0x30d5,
+  0x30a1,
+  0x30e9,
+  0x30c3,
+  0x30c9,
+  0x30d5,
+  0x30a3,
+  0x30fc,
+  0x30c8,
+  0x30d6,
+  0x30c3,
+  0x30b7,
+  0x30a7,
+  0x30eb,
+  0x30d5,
+  0x30e9,
+  0x30f3,
+  0x30d8,
+  0x30af,
+  0x30bf,
+  0x30fc,
+  0x30eb,
+  0x30da,
+  0x30bd,
+  0x30da,
+  0x30cb,
+  0x30d2,
+  0x30d8,
+  0x30eb,
+  0x30c4,
+  0x30da,
+  0x30f3,
+  0x30b9,
+  0x30da,
+  0x30fc,
+  0x30b8,
+  0x30d9,
+  0x30fc,
+  0x30bf,
+  0x30dd,
+  0x30a4,
+  0x30f3,
+  0x30c8,
+  0x30dc,
+  0x30eb,
+  0x30c8,
+  0x30db,
+  0x30f3,
+  0x30dd,
+  0x30f3,
+  0x30c9,
+  0x30db,
+  0x30fc,
+  0x30eb,
+  0x30db,
+  0x30fc,
+  0x30f3,
+  0x30de,
+  0x30a4,
+  0x30af,
+  0x30ed,
+  0x30de,
+  0x30a4,
+  0x30eb,
+  0x30de,
+  0x30c3,
+  0x30cf,
+  0x30de,
+  0x30eb,
+  0x30af,
+  0x30de,
+  0x30f3,
+  0x30b7,
+  0x30e7,
+  0x30f3,
+  0x30df,
+  0x30af,
+  0x30ed,
+  0x30f3,
+  0x30df,
+  0x30ea,
+  0x30df,
+  0x30ea,
+  0x30d0,
+  0x30fc,
+  0x30eb,
+  0x30e1,
+  0x30ac,
+  0x30e1,
+  0x30ac,
+  0x30c8,
+  0x30f3,
+  0x30e4,
+  0x30fc,
+  0x30c9,
+  0x30e4,
+  0x30fc,
+  0x30eb,
+  0x30e6,
+  0x30a2,
+  0x30f3,
+  0x30ea,
+  0x30c3,
+  0x30c8,
+  0x30eb,
+  0x30ea,
+  0x30e9,
+  0x30eb,
+  0x30d4,
+  0x30fc,
+  0x30eb,
+  0x30fc,
+  0x30d6,
+  0x30eb,
+  0x30ec,
+  0x30e0,
+  0x30ec,
+  0x30f3,
+  0x30c8,
+  0x30b2,
+  0x30f3,
+  0x30,
+  0x70b9,
+  0x31,
+  0x70b9,
+  0x32,
+  0x70b9,
+  0x33,
+  0x70b9,
+  0x34,
+  0x70b9,
+  0x35,
+  0x70b9,
+  0x36,
+  0x70b9,
+  0x37,
+  0x70b9,
+  0x38,
+  0x70b9,
+  0x39,
+  0x70b9,
+  0x31,
+  0x30,
+  0x70b9,
+  0x31,
+  0x31,
+  0x70b9,
+  0x31,
+  0x32,
+  0x70b9,
+  0x31,
+  0x33,
+  0x70b9,
+  0x31,
+  0x34,
+  0x70b9,
+  0x31,
+  0x35,
+  0x70b9,
+  0x31,
+  0x36,
+  0x70b9,
+  0x31,
+  0x37,
+  0x70b9,
+  0x31,
+  0x38,
+  0x70b9,
+  0x31,
+  0x39,
+  0x70b9,
+  0x32,
+  0x30,
+  0x70b9,
+  0x32,
+  0x31,
+  0x70b9,
+  0x32,
+  0x32,
+  0x70b9,
+  0x32,
+  0x33,
+  0x70b9,
+  0x32,
+  0x34,
+  0x70b9,
+  0x68,
+  0x50,
+  0x61,
+  0x64,
+  0x61,
+  0x41,
+  0x55,
+  0x62,
+  0x61,
+  0x72,
+  0x6f,
+  0x56,
+  0x70,
+  0x63,
+  0x64,
+  0x6d,
+  0x64,
+  0x6d,
+  0xb2,
+  0x64,
+  0x6d,
+  0xb3,
+  0x49,
+  0x55,
+  0x5e73,
+  0x6210,
+  0x662d,
+  0x548c,
+  0x5927,
+  0x6b63,
+  0x660e,
+  0x6cbb,
+  0x682a,
+  0x5f0f,
+  0x4f1a,
+  0x793e,
+  0x70,
+  0x41,
+  0x6e,
+  0x41,
+  0x3bc,
+  0x41,
+  0x6d,
+  0x41,
+  0x6b,
+  0x41,
+  0x4b,
+  0x42,
+  0x4d,
+  0x42,
+  0x47,
+  0x42,
+  0x63,
+  0x61,
+  0x6c,
+  0x6b,
+  0x63,
+  0x61,
+  0x6c,
+  0x70,
+  0x46,
+  0x6e,
+  0x46,
+  0x3bc,
+  0x46,
+  0x3bc,
+  0x67,
+  0x6d,
+  0x67,
+  0x6b,
+  0x67,
+  0x48,
+  0x7a,
+  0x6b,
+  0x48,
+  0x7a,
+  0x4d,
+  0x48,
+  0x7a,
+  0x47,
+  0x48,
+  0x7a,
+  0x54,
+  0x48,
+  0x7a,
+  0x3bc,
+  0x2113,
+  0x6d,
+  0x2113,
+  0x64,
+  0x2113,
+  0x6b,
+  0x2113,
+  0x66,
+  0x6d,
+  0x6e,
+  0x6d,
+  0x3bc,
+  0x6d,
+  0x6d,
+  0x6d,
+  0x63,
+  0x6d,
+  0x6b,
+  0x6d,
+  0x6d,
+  0x6d,
+  0xb2,
+  0x63,
+  0x6d,
+  0xb2,
+  0x6b,
+  0x6d,
+  0xb2,
+  0x6d,
+  0x6d,
+  0xb3,
+  0x63,
+  0x6d,
+  0xb3,
+  0x6b,
+  0x6d,
+  0xb3,
+  0x6d,
+  0x2215,
+  0x73,
+  0x6d,
+  0x2215,
+  0x73,
+  0xb2,
+  0x6b,
+  0x50,
+  0x61,
+  0x4d,
+  0x50,
+  0x61,
+  0x47,
+  0x50,
+  0x61,
+  0x72,
+  0x61,
+  0x64,
+  0x72,
+  0x61,
+  0x64,
+  0x2215,
+  0x73,
+  0x72,
+  0x61,
+  0x64,
+  0x2215,
+  0x73,
+  0xb2,
+  0x70,
+  0x73,
+  0x6e,
+  0x73,
+  0x3bc,
+  0x73,
+  0x6d,
+  0x73,
+  0x70,
+  0x56,
+  0x6e,
+  0x56,
+  0x3bc,
+  0x56,
+  0x6d,
+  0x56,
+  0x6b,
+  0x56,
+  0x4d,
+  0x56,
+  0x70,
+  0x57,
+  0x6e,
+  0x57,
+  0x3bc,
+  0x57,
+  0x6d,
+  0x57,
+  0x6b,
+  0x57,
+  0x4d,
+  0x57,
+  0x6b,
+  0x3a9,
+  0x4d,
+  0x3a9,
+  0x61,
+  0x2e,
+  0x6d,
+  0x2e,
+  0x42,
+  0x71,
+  0x63,
+  0x63,
+  0x43,
+  0x2215,
+  0x6b,
+  0x67,
+  0x43,
+  0x6f,
+  0x2e,
+  0x64,
+  0x42,
+  0x47,
+  0x79,
+  0x68,
+  0x61,
+  0x48,
+  0x50,
+  0x69,
+  0x6e,
+  0x4b,
+  0x4b,
+  0x4b,
+  0x4d,
+  0x6b,
+  0x74,
+  0x6c,
+  0x6d,
+  0x6c,
+  0x6e,
+  0x6c,
+  0x6f,
+  0x67,
+  0x6c,
+  0x78,
+  0x6d,
+  0x62,
+  0x6d,
+  0x69,
+  0x6c,
+  0x6d,
+  0x6f,
+  0x6c,
+  0x50,
+  0x48,
+  0x70,
+  0x2e,
+  0x6d,
+  0x2e,
+  0x50,
+  0x50,
+  0x4d,
+  0x50,
+  0x52,
+  0x53,
+  0x76,
+  0x57,
+  0x62,
+  0x56,
+  0x2215,
+  0x6d,
+  0x41,
+  0x2215,
+  0x6d,
+  0x31,
+  0x65e5,
+  0x32,
+  0x65e5,
+  0x33,
+  0x65e5,
+  0x34,
+  0x65e5,
+  0x35,
+  0x65e5,
+  0x36,
+  0x65e5,
+  0x37,
+  0x65e5,
+  0x38,
+  0x65e5,
+  0x39,
+  0x65e5,
+  0x31,
+  0x30,
+  0x65e5,
+  0x31,
+  0x31,
+  0x65e5,
+  0x31,
+  0x32,
+  0x65e5,
+  0x31,
+  0x33,
+  0x65e5,
+  0x31,
+  0x34,
+  0x65e5,
+  0x31,
+  0x35,
+  0x65e5,
+  0x31,
+  0x36,
+  0x65e5,
+  0x31,
+  0x37,
+  0x65e5,
+  0x31,
+  0x38,
+  0x65e5,
+  0x31,
+  0x39,
+  0x65e5,
+  0x32,
+  0x30,
+  0x65e5,
+  0x32,
+  0x31,
+  0x65e5,
+  0x32,
+  0x32,
+  0x65e5,
+  0x32,
+  0x33,
+  0x65e5,
+  0x32,
+  0x34,
+  0x65e5,
+  0x32,
+  0x35,
+  0x65e5,
+  0x32,
+  0x36,
+  0x65e5,
+  0x32,
+  0x37,
+  0x65e5,
+  0x32,
+  0x38,
+  0x65e5,
+  0x32,
+  0x39,
+  0x65e5,
+  0x33,
+  0x30,
+  0x65e5,
+  0x33,
+  0x31,
+  0x65e5,
+  0x67,
+  0x61,
+  0x6c,
+  0x8c48,
+  0x66f4,
+  0x8cc8,
+  0x6ed1,
+  0x4e32,
+  0x53e5,
+  0x5951,
+  0x5587,
+  0x5948,
+  0x61f6,
+  0x7669,
+  0x7f85,
+  0x863f,
+  0x87ba,
+  0x88f8,
+  0x908f,
+  0x6a02,
+  0x6d1b,
+  0x70d9,
+  0x73de,
+  0x843d,
+  0x916a,
+  0x99f1,
+  0x4e82,
+  0x5375,
+  0x6b04,
+  0x721b,
+  0x862d,
+  0x9e1e,
+  0x5d50,
+  0x6feb,
+  0x85cd,
+  0x8964,
+  0x62c9,
+  0x81d8,
+  0x881f,
+  0x5eca,
+  0x6717,
+  0x6d6a,
+  0x72fc,
+  0x90ce,
+  0x4f86,
+  0x51b7,
+  0x52de,
+  0x64c4,
+  0x6ad3,
+  0x7210,
+  0x76e7,
+  0x8606,
+  0x865c,
+  0x8def,
+  0x9732,
+  0x9b6f,
+  0x9dfa,
+  0x788c,
+  0x797f,
+  0x7da0,
+  0x83c9,
+  0x9304,
+  0x8ad6,
+  0x58df,
+  0x5f04,
+  0x7c60,
+  0x807e,
+  0x7262,
+  0x78ca,
+  0x8cc2,
+  0x96f7,
+  0x58d8,
+  0x5c62,
+  0x6a13,
+  0x6dda,
+  0x6f0f,
+  0x7d2f,
+  0x7e37,
+  0x964b,
+  0x52d2,
+  0x808b,
+  0x51dc,
+  0x51cc,
+  0x7a1c,
+  0x7dbe,
+  0x83f1,
+  0x9675,
+  0x8b80,
+  0x62cf,
+  0x8afe,
+  0x4e39,
+  0x5be7,
+  0x6012,
+  0x7387,
+  0x7570,
+  0x5317,
+  0x78fb,
+  0x4fbf,
+  0x5fa9,
+  0x4e0d,
+  0x6ccc,
+  0x6578,
+  0x7d22,
+  0x53c3,
+  0x585e,
+  0x7701,
+  0x8449,
+  0x8aaa,
+  0x6bba,
+  0x6c88,
+  0x62fe,
+  0x82e5,
+  0x63a0,
+  0x7565,
+  0x4eae,
+  0x5169,
+  0x51c9,
+  0x6881,
+  0x7ce7,
+  0x826f,
+  0x8ad2,
+  0x91cf,
+  0x52f5,
+  0x5442,
+  0x5eec,
+  0x65c5,
+  0x6ffe,
+  0x792a,
+  0x95ad,
+  0x9a6a,
+  0x9e97,
+  0x9ece,
+  0x66c6,
+  0x6b77,
+  0x8f62,
+  0x5e74,
+  0x6190,
+  0x6200,
+  0x649a,
+  0x6f23,
+  0x7149,
+  0x7489,
+  0x79ca,
+  0x7df4,
+  0x806f,
+  0x8f26,
+  0x84ee,
+  0x9023,
+  0x934a,
+  0x5217,
+  0x52a3,
+  0x54bd,
+  0x70c8,
+  0x88c2,
+  0x5ec9,
+  0x5ff5,
+  0x637b,
+  0x6bae,
+  0x7c3e,
+  0x7375,
+  0x4ee4,
+  0x56f9,
+  0x5dba,
+  0x601c,
+  0x73b2,
+  0x7469,
+  0x7f9a,
+  0x8046,
+  0x9234,
+  0x96f6,
+  0x9748,
+  0x9818,
+  0x4f8b,
+  0x79ae,
+  0x91b4,
+  0x96b8,
+  0x60e1,
+  0x4e86,
+  0x50da,
+  0x5bee,
+  0x5c3f,
+  0x6599,
+  0x71ce,
+  0x7642,
+  0x84fc,
+  0x907c,
+  0x6688,
+  0x962e,
+  0x5289,
+  0x677b,
+  0x67f3,
+  0x6d41,
+  0x6e9c,
+  0x7409,
+  0x7559,
+  0x786b,
+  0x7d10,
+  0x985e,
+  0x622e,
+  0x9678,
+  0x502b,
+  0x5d19,
+  0x6dea,
+  0x8f2a,
+  0x5f8b,
+  0x6144,
+  0x6817,
+  0x9686,
+  0x5229,
+  0x540f,
+  0x5c65,
+  0x6613,
+  0x674e,
+  0x68a8,
+  0x6ce5,
+  0x7406,
+  0x75e2,
+  0x7f79,
+  0x88cf,
+  0x88e1,
+  0x96e2,
+  0x533f,
+  0x6eba,
+  0x541d,
+  0x71d0,
+  0x7498,
+  0x85fa,
+  0x96a3,
+  0x9c57,
+  0x9e9f,
+  0x6797,
+  0x6dcb,
+  0x81e8,
+  0x7b20,
+  0x7c92,
+  0x72c0,
+  0x7099,
+  0x8b58,
+  0x4ec0,
+  0x8336,
+  0x523a,
+  0x5207,
+  0x5ea6,
+  0x62d3,
+  0x7cd6,
+  0x5b85,
+  0x6d1e,
+  0x66b4,
+  0x8f3b,
+  0x964d,
+  0x5ed3,
+  0x5140,
+  0x55c0,
+  0x585a,
+  0x6674,
+  0x51de,
+  0x732a,
+  0x76ca,
+  0x793c,
+  0x795e,
+  0x7965,
+  0x798f,
+  0x9756,
+  0x7cbe,
+  0x8612,
+  0x8af8,
+  0x9038,
+  0x90fd,
+  0x98ef,
+  0x98fc,
+  0x9928,
+  0x9db4,
+  0x4fae,
+  0x50e7,
+  0x514d,
+  0x52c9,
+  0x52e4,
+  0x5351,
+  0x559d,
+  0x5606,
+  0x5668,
+  0x5840,
+  0x58a8,
+  0x5c64,
+  0x6094,
+  0x6168,
+  0x618e,
+  0x61f2,
+  0x654f,
+  0x65e2,
+  0x6691,
+  0x6885,
+  0x6d77,
+  0x6e1a,
+  0x6f22,
+  0x716e,
+  0x722b,
+  0x7422,
+  0x7891,
+  0x7949,
+  0x7948,
+  0x7950,
+  0x7956,
+  0x798d,
+  0x798e,
+  0x7a40,
+  0x7a81,
+  0x7bc0,
+  0x7e09,
+  0x7e41,
+  0x7f72,
+  0x8005,
+  0x81ed,
+  0x8279,
+  0x8457,
+  0x8910,
+  0x8996,
+  0x8b01,
+  0x8b39,
+  0x8cd3,
+  0x8d08,
+  0x8fb6,
+  0x96e3,
+  0x97ff,
+  0x983b,
+  0x66,
+  0x66,
+  0x66,
+  0x69,
+  0x66,
+  0x6c,
+  0x66,
+  0x66,
+  0x6c,
+  0x17f,
+  0x74,
+  0x73,
+  0x74,
+  0x574,
+  0x576,
+  0x574,
+  0x565,
+  0x574,
+  0x56b,
+  0x57e,
+  0x576,
+  0x574,
+  0x56d,
+  0x5d9,
+  0x5b4,
+  0x5f2,
+  0x5b7,
+  0x5e2,
+  0x5d4,
+  0x5db,
+  0x5dc,
+  0x5dd,
+  0x5e8,
+  0x5ea,
+  0x5e9,
+  0x5c1,
+  0x5e9,
+  0x5c2,
+  0xfb49,
+  0x5c1,
+  0xfb49,
+  0x5c2,
+  0x5d0,
+  0x5b7,
+  0x5d0,
+  0x5b8,
+  0x5d0,
+  0x5bc,
+  0x5d1,
+  0x5bc,
+  0x5d2,
+  0x5bc,
+  0x5d3,
+  0x5bc,
+  0x5d4,
+  0x5bc,
+  0x5d5,
+  0x5bc,
+  0x5d6,
+  0x5bc,
+  0x5d8,
+  0x5bc,
+  0x5d9,
+  0x5bc,
+  0x5da,
+  0x5bc,
+  0x5db,
+  0x5bc,
+  0x5dc,
+  0x5bc,
+  0x5de,
+  0x5bc,
+  0x5e0,
+  0x5bc,
+  0x5e1,
+  0x5bc,
+  0x5e3,
+  0x5bc,
+  0x5e4,
+  0x5bc,
+  0x5e6,
+  0x5bc,
+  0x5e7,
+  0x5bc,
+  0x5e8,
+  0x5bc,
+  0x5e9,
+  0x5bc,
+  0x5ea,
+  0x5bc,
+  0x5d5,
+  0x5b9,
+  0x5d1,
+  0x5bf,
+  0x5db,
+  0x5bf,
+  0x5e4,
+  0x5bf,
+  0x5d0,
+  0x5dc,
+  0x671,
+  0x67b,
+  0x67e,
+  0x680,
+  0x67a,
+  0x67f,
+  0x679,
+  0x6a4,
+  0x6a6,
+  0x684,
+  0x683,
+  0x686,
+  0x687,
+  0x68d,
+  0x68c,
+  0x68e,
+  0x688,
+  0x698,
+  0x691,
+  0x6a9,
+  0x6af,
+  0x6b3,
+  0x6b1,
+  0x6ba,
+  0x6bb,
+  0x6c0,
+  0x6be,
+  0x6d3,
+  0x6ad,
+  0x6c6,
+  0x6c8,
+  0x677,
+  0x6cb,
+  0x6c5,
+  0x6c9,
+  0x6d0,
+  0x649,
+  0x626,
+  0x627,
+  0x626,
+  0x6d5,
+  0x626,
+  0x648,
+  0x626,
+  0x6c7,
+  0x626,
+  0x6c6,
+  0x626,
+  0x6c8,
+  0x626,
+  0x6d0,
+  0x626,
+  0x649,
+  0x6cc,
+  0x626,
+  0x62c,
+  0x626,
+  0x62d,
+  0x626,
+  0x645,
+  0x626,
+  0x64a,
+  0x628,
+  0x62c,
+  0x628,
+  0x62d,
+  0x628,
+  0x62e,
+  0x628,
+  0x645,
+  0x628,
+  0x649,
+  0x628,
+  0x64a,
+  0x62a,
+  0x62c,
+  0x62a,
+  0x62d,
+  0x62a,
+  0x62e,
+  0x62a,
+  0x645,
+  0x62a,
+  0x649,
+  0x62a,
+  0x64a,
+  0x62b,
+  0x62c,
+  0x62b,
+  0x645,
+  0x62b,
+  0x649,
+  0x62b,
+  0x64a,
+  0x62c,
+  0x62d,
+  0x62c,
+  0x645,
+  0x62d,
+  0x645,
+  0x62e,
+  0x62c,
+  0x62e,
+  0x62d,
+  0x62e,
+  0x645,
+  0x633,
+  0x62c,
+  0x633,
+  0x62d,
+  0x633,
+  0x62e,
+  0x633,
+  0x645,
+  0x635,
+  0x62d,
+  0x635,
+  0x645,
+  0x636,
+  0x62c,
+  0x636,
+  0x62d,
+  0x636,
+  0x62e,
+  0x636,
+  0x645,
+  0x637,
+  0x62d,
+  0x637,
+  0x645,
+  0x638,
+  0x645,
+  0x639,
+  0x62c,
+  0x639,
+  0x645,
+  0x63a,
+  0x62c,
+  0x63a,
+  0x645,
+  0x641,
+  0x62c,
+  0x641,
+  0x62d,
+  0x641,
+  0x62e,
+  0x641,
+  0x645,
+  0x641,
+  0x649,
+  0x641,
+  0x64a,
+  0x642,
+  0x62d,
+  0x642,
+  0x645,
+  0x642,
+  0x649,
+  0x642,
+  0x64a,
+  0x643,
+  0x627,
+  0x643,
+  0x62c,
+  0x643,
+  0x62d,
+  0x643,
+  0x62e,
+  0x643,
+  0x644,
+  0x643,
+  0x645,
+  0x643,
+  0x649,
+  0x643,
+  0x64a,
+  0x644,
+  0x62c,
+  0x644,
+  0x62d,
+  0x644,
+  0x62e,
+  0x644,
+  0x645,
+  0x644,
+  0x649,
+  0x644,
+  0x64a,
+  0x645,
+  0x62c,
+  0x645,
+  0x645,
+  0x645,
+  0x649,
+  0x645,
+  0x64a,
+  0x646,
+  0x62c,
+  0x646,
+  0x62d,
+  0x646,
+  0x62e,
+  0x646,
+  0x645,
+  0x646,
+  0x649,
+  0x646,
+  0x64a,
+  0x647,
+  0x62c,
+  0x647,
+  0x645,
+  0x647,
+  0x649,
+  0x647,
+  0x64a,
+  0x64a,
+  0x62d,
+  0x64a,
+  0x62e,
+  0x64a,
+  0x649,
+  0x630,
+  0x670,
+  0x631,
+  0x670,
+  0x649,
+  0x670,
+  0x20,
+  0x64c,
+  0x651,
+  0x20,
+  0x64d,
+  0x651,
+  0x20,
+  0x64e,
+  0x651,
+  0x20,
+  0x64f,
+  0x651,
+  0x20,
+  0x650,
+  0x651,
+  0x20,
+  0x651,
+  0x670,
+  0x626,
+  0x631,
+  0x626,
+  0x632,
+  0x626,
+  0x646,
+  0x628,
+  0x631,
+  0x628,
+  0x632,
+  0x628,
+  0x646,
+  0x62a,
+  0x631,
+  0x62a,
+  0x632,
+  0x62a,
+  0x646,
+  0x62b,
+  0x631,
+  0x62b,
+  0x632,
+  0x62b,
+  0x646,
+  0x645,
+  0x627,
+  0x646,
+  0x631,
+  0x646,
+  0x632,
+  0x646,
+  0x646,
+  0x64a,
+  0x631,
+  0x64a,
+  0x632,
+  0x626,
+  0x62e,
+  0x626,
+  0x647,
+  0x628,
+  0x647,
+  0x62a,
+  0x647,
+  0x635,
+  0x62e,
+  0x644,
+  0x647,
+  0x646,
+  0x647,
+  0x647,
+  0x670,
+  0x62b,
+  0x647,
+  0x633,
+  0x647,
+  0x634,
+  0x645,
+  0x634,
+  0x647,
+  0x640,
+  0x64e,
+  0x651,
+  0x640,
+  0x64f,
+  0x651,
+  0x640,
+  0x650,
+  0x651,
+  0x637,
+  0x649,
+  0x637,
+  0x64a,
+  0x639,
+  0x649,
+  0x639,
+  0x64a,
+  0x63a,
+  0x649,
+  0x63a,
+  0x64a,
+  0x633,
+  0x649,
+  0x633,
+  0x64a,
+  0x634,
+  0x649,
+  0x634,
+  0x64a,
+  0x62d,
+  0x649,
+  0x62c,
+  0x649,
+  0x62c,
+  0x64a,
+  0x62e,
+  0x649,
+  0x635,
+  0x649,
+  0x635,
+  0x64a,
+  0x636,
+  0x649,
+  0x636,
+  0x64a,
+  0x634,
+  0x62c,
+  0x634,
+  0x62d,
+  0x634,
+  0x62e,
+  0x634,
+  0x631,
+  0x633,
+  0x631,
+  0x635,
+  0x631,
+  0x636,
+  0x631,
+  0x627,
+  0x64b,
+  0x62a,
+  0x62c,
+  0x645,
+  0x62a,
+  0x62d,
+  0x62c,
+  0x62a,
+  0x62d,
+  0x645,
+  0x62a,
+  0x62e,
+  0x645,
+  0x62a,
+  0x645,
+  0x62c,
+  0x62a,
+  0x645,
+  0x62d,
+  0x62a,
+  0x645,
+  0x62e,
+  0x62d,
+  0x645,
+  0x64a,
+  0x62d,
+  0x645,
+  0x649,
+  0x633,
+  0x62d,
+  0x62c,
+  0x633,
+  0x62c,
+  0x62d,
+  0x633,
+  0x62c,
+  0x649,
+  0x633,
+  0x645,
+  0x62d,
+  0x633,
+  0x645,
+  0x62c,
+  0x633,
+  0x645,
+  0x645,
+  0x635,
+  0x62d,
+  0x62d,
+  0x635,
+  0x645,
+  0x645,
+  0x634,
+  0x62d,
+  0x645,
+  0x634,
+  0x62c,
+  0x64a,
+  0x634,
+  0x645,
+  0x62e,
+  0x634,
+  0x645,
+  0x645,
+  0x636,
+  0x62d,
+  0x649,
+  0x636,
+  0x62e,
+  0x645,
+  0x637,
+  0x645,
+  0x62d,
+  0x637,
+  0x645,
+  0x645,
+  0x637,
+  0x645,
+  0x64a,
+  0x639,
+  0x62c,
+  0x645,
+  0x639,
+  0x645,
+  0x645,
+  0x639,
+  0x645,
+  0x649,
+  0x63a,
+  0x645,
+  0x645,
+  0x63a,
+  0x645,
+  0x64a,
+  0x63a,
+  0x645,
+  0x649,
+  0x641,
+  0x62e,
+  0x645,
+  0x642,
+  0x645,
+  0x62d,
+  0x642,
+  0x645,
+  0x645,
+  0x644,
+  0x62d,
+  0x645,
+  0x644,
+  0x62d,
+  0x64a,
+  0x644,
+  0x62d,
+  0x649,
+  0x644,
+  0x62c,
+  0x62c,
+  0x644,
+  0x62e,
+  0x645,
+  0x644,
+  0x645,
+  0x62d,
+  0x645,
+  0x62d,
+  0x62c,
+  0x645,
+  0x62d,
+  0x64a,
+  0x645,
+  0x62c,
+  0x62d,
+  0x645,
+  0x62e,
+  0x645,
+  0x645,
+  0x62c,
+  0x62e,
+  0x647,
+  0x645,
+  0x62c,
+  0x647,
+  0x645,
+  0x645,
+  0x646,
+  0x62d,
+  0x645,
+  0x646,
+  0x62d,
+  0x649,
+  0x646,
+  0x62c,
+  0x645,
+  0x646,
+  0x62c,
+  0x649,
+  0x646,
+  0x645,
+  0x64a,
+  0x646,
+  0x645,
+  0x649,
+  0x64a,
+  0x645,
+  0x645,
+  0x628,
+  0x62e,
+  0x64a,
+  0x62a,
+  0x62c,
+  0x64a,
+  0x62a,
+  0x62c,
+  0x649,
+  0x62a,
+  0x62e,
+  0x64a,
+  0x62a,
+  0x62e,
+  0x649,
+  0x62a,
+  0x645,
+  0x64a,
+  0x62a,
+  0x645,
+  0x649,
+  0x62c,
+  0x645,
+  0x64a,
+  0x62c,
+  0x62d,
+  0x649,
+  0x62c,
+  0x645,
+  0x649,
+  0x633,
+  0x62e,
+  0x649,
+  0x635,
+  0x62d,
+  0x64a,
+  0x634,
+  0x62d,
+  0x64a,
+  0x636,
+  0x62d,
+  0x64a,
+  0x644,
+  0x62c,
+  0x64a,
+  0x644,
+  0x645,
+  0x64a,
+  0x64a,
+  0x62c,
+  0x64a,
+  0x64a,
+  0x645,
+  0x64a,
+  0x645,
+  0x645,
+  0x64a,
+  0x642,
+  0x645,
+  0x64a,
+  0x646,
+  0x62d,
+  0x64a,
+  0x639,
+  0x645,
+  0x64a,
+  0x643,
+  0x645,
+  0x64a,
+  0x646,
+  0x62c,
+  0x62d,
+  0x645,
+  0x62e,
+  0x64a,
+  0x644,
+  0x62c,
+  0x645,
+  0x643,
+  0x645,
+  0x645,
+  0x62c,
+  0x62d,
+  0x64a,
+  0x62d,
+  0x62c,
+  0x64a,
+  0x645,
+  0x62c,
+  0x64a,
+  0x641,
+  0x645,
+  0x64a,
+  0x628,
+  0x62d,
+  0x64a,
+  0x633,
+  0x62e,
+  0x64a,
+  0x646,
+  0x62c,
+  0x64a,
+  0x635,
+  0x644,
+  0x6d2,
+  0x642,
+  0x644,
+  0x6d2,
+  0x627,
+  0x644,
+  0x644,
+  0x647,
+  0x627,
+  0x643,
+  0x628,
+  0x631,
+  0x645,
+  0x62d,
+  0x645,
+  0x62f,
+  0x635,
+  0x644,
+  0x639,
+  0x645,
+  0x631,
+  0x633,
+  0x648,
+  0x644,
+  0x639,
+  0x644,
+  0x64a,
+  0x647,
+  0x648,
+  0x633,
+  0x644,
+  0x645,
+  0x635,
+  0x644,
+  0x649,
+  0x635,
+  0x644,
+  0x649,
+  0x20,
+  0x627,
+  0x644,
+  0x644,
+  0x647,
+  0x20,
+  0x639,
+  0x644,
+  0x64a,
+  0x647,
+  0x20,
+  0x648,
+  0x633,
+  0x644,
+  0x645,
+  0x62c,
+  0x644,
+  0x20,
+  0x62c,
+  0x644,
+  0x627,
+  0x644,
+  0x647,
+  0x631,
+  0x6cc,
+  0x627,
+  0x644,
+  0x2025,
+  0x2014,
+  0x2013,
+  0x5f,
+  0x7b,
+  0x7d,
+  0x3014,
+  0x3015,
+  0x3010,
+  0x3011,
+  0x300a,
+  0x300b,
+  0x300c,
+  0x300d,
+  0x300e,
+  0x300f,
+  0x5b,
+  0x5d,
+  0x203e,
+  0x2c,
+  0x3001,
+  0x23,
+  0x26,
+  0x2a,
+  0x2d,
+  0x5c,
+  0x24,
+  0x25,
+  0x40,
+  0x20,
+  0x64b,
+  0x640,
+  0x64b,
+  0x640,
+  0x651,
+  0x20,
+  0x652,
+  0x640,
+  0x652,
+  0x621,
+  0x622,
+  0x623,
+  0x624,
+  0x625,
+  0x629,
+  0x644,
+  0x622,
+  0x644,
+  0x623,
+  0x644,
+  0x625,
+  0x22,
+  0x27,
+  0x5e,
+  0x7c,
+  0x7e,
+  0x2985,
+  0x2986,
+  0x3002,
+  0x30fb,
+  0x30a5,
+  0x30e3,
+  0x3164,
+  0x3131,
+  0x3132,
+  0x3133,
+  0x3134,
+  0x3135,
+  0x3136,
+  0x3137,
+  0x3138,
+  0x3139,
+  0x313a,
+  0x313b,
+  0x313c,
+  0x313d,
+  0x313e,
+  0x313f,
+  0x3140,
+  0x3141,
+  0x3142,
+  0x3143,
+  0x3144,
+  0x3145,
+  0x3146,
+  0x3147,
+  0x3148,
+  0x3149,
+  0x314a,
+  0x314b,
+  0x314c,
+  0x314d,
+  0x314e,
+  0x314f,
+  0x3150,
+  0x3151,
+  0x3152,
+  0x3153,
+  0x3154,
+  0x3155,
+  0x3156,
+  0x3157,
+  0x3158,
+  0x3159,
+  0x315a,
+  0x315b,
+  0x315c,
+  0x315d,
+  0x315e,
+  0x315f,
+  0x3160,
+  0x3161,
+  0x3162,
+  0x3163,
+  0xa2,
+  0xa3,
+  0xac,
+  0xaf,
+  0xa6,
+  0xa5,
+  0x20a9,
+  0x2502,
+  0x2191,
+  0x2193,
+  0x25a0,
+  0x25cb,
+  0x1d157,
+  0x1d165,
+  0x1d158,
+  0x1d165,
+  0x1d15f,
+  0x1d16e,
+  0x1d15f,
+  0x1d16f,
+  0x1d15f,
+  0x1d170,
+  0x1d15f,
+  0x1d171,
+  0x1d15f,
+  0x1d172,
+  0x1d1b9,
+  0x1d165,
+  0x1d1ba,
+  0x1d165,
+  0x1d1bb,
+  0x1d16e,
+  0x1d1bc,
+  0x1d16e,
+  0x1d1bb,
+  0x1d16f,
+  0x1d1bc,
+  0x1d16f,
+  0x392,
+  0x394,
+  0x396,
+  0x39a,
+  0x39b,
+  0x39c,
+  0x39d,
+  0x39e,
+  0x3f4,
+  0x3a4,
+  0x3a6,
+  0x3a7,
+  0x3a8,
+  0x2207,
+  0x3b6,
+  0x3bb,
+  0x3bd,
+  0x3be,
+  0x3c3,
+  0x3c4,
+  0x3c8,
+  0x2202,
+  0x3f5,
+  0x3d1,
+  0x3f0,
+  0x3d5,
+  0x3f1,
+  0x3d6,
+  0x4e3d,
+  0x4e38,
+  0x4e41,
+  0x20122,
+  0x4f60,
+  0x4fbb,
+  0x5002,
+  0x507a,
+  0x5099,
+  0x50cf,
+  0x349e,
+  0x2063a,
+  0x5154,
+  0x5164,
+  0x5177,
+  0x2051c,
+  0x34b9,
+  0x5167,
+  0x518d,
+  0x2054b,
+  0x5197,
+  0x51a4,
+  0x4ecc,
+  0x51ac,
+  0x51b5,
+  0x291df,
+  0x5203,
+  0x34df,
+  0x523b,
+  0x5246,
+  0x5272,
+  0x5277,
+  0x3515,
+  0x52c7,
+  0x52fa,
+  0x5305,
+  0x5306,
+  0x5349,
+  0x535a,
+  0x5373,
+  0x537d,
+  0x537f,
+  0x20a2c,
+  0x7070,
+  0x53ca,
+  0x53df,
+  0x20b63,
+  0x53eb,
+  0x53f1,
+  0x5406,
+  0x549e,
+  0x5438,
+  0x5448,
+  0x5468,
+  0x54a2,
+  0x54f6,
+  0x5510,
+  0x5553,
+  0x5563,
+  0x5584,
+  0x5599,
+  0x55ab,
+  0x55b3,
+  0x55c2,
+  0x5716,
+  0x5717,
+  0x5651,
+  0x5674,
+  0x58ee,
+  0x57ce,
+  0x57f4,
+  0x580d,
+  0x578b,
+  0x5832,
+  0x5831,
+  0x58ac,
+  0x214e4,
+  0x58f2,
+  0x58f7,
+  0x5906,
+  0x591a,
+  0x5922,
+  0x5962,
+  0x216a8,
+  0x216ea,
+  0x59ec,
+  0x5a1b,
+  0x5a27,
+  0x59d8,
+  0x5a66,
+  0x36ee,
+  0x36fc,
+  0x5b08,
+  0x5b3e,
+  0x219c8,
+  0x5bc3,
+  0x5bd8,
+  0x5bf3,
+  0x21b18,
+  0x5bff,
+  0x5c06,
+  0x5f53,
+  0x3781,
+  0x5c60,
+  0x5cc0,
+  0x5c8d,
+  0x21de4,
+  0x5d43,
+  0x21de6,
+  0x5d6e,
+  0x5d6b,
+  0x5d7c,
+  0x5de1,
+  0x5de2,
+  0x382f,
+  0x5dfd,
+  0x5e28,
+  0x5e3d,
+  0x5e69,
+  0x3862,
+  0x22183,
+  0x387c,
+  0x5eb0,
+  0x5eb3,
+  0x5eb6,
+  0x2a392,
+  0x22331,
+  0x8201,
+  0x5f22,
+  0x38c7,
+  0x232b8,
+  0x261da,
+  0x5f62,
+  0x5f6b,
+  0x38e3,
+  0x5f9a,
+  0x5fcd,
+  0x5fd7,
+  0x5ff9,
+  0x6081,
+  0x393a,
+  0x391c,
+  0x226d4,
+  0x60c7,
+  0x6148,
+  0x614c,
+  0x614e,
+  0x617a,
+  0x61b2,
+  0x61a4,
+  0x61af,
+  0x61de,
+  0x621b,
+  0x625d,
+  0x62b1,
+  0x62d4,
+  0x6350,
+  0x22b0c,
+  0x633d,
+  0x62fc,
+  0x6368,
+  0x6383,
+  0x63e4,
+  0x22bf1,
+  0x6422,
+  0x63c5,
+  0x63a9,
+  0x3a2e,
+  0x6469,
+  0x647e,
+  0x649d,
+  0x6477,
+  0x3a6c,
+  0x656c,
+  0x2300a,
+  0x65e3,
+  0x66f8,
+  0x6649,
+  0x3b19,
+  0x3b08,
+  0x3ae4,
+  0x5192,
+  0x5195,
+  0x6700,
+  0x669c,
+  0x80ad,
+  0x43d9,
+  0x671b,
+  0x6721,
+  0x675e,
+  0x6753,
+  0x233c3,
+  0x3b49,
+  0x67fa,
+  0x6785,
+  0x6852,
+  0x2346d,
+  0x688e,
+  0x681f,
+  0x6914,
+  0x3b9d,
+  0x6942,
+  0x69a3,
+  0x69ea,
+  0x6aa8,
+  0x236a3,
+  0x6adb,
+  0x3c18,
+  0x6b21,
+  0x238a7,
+  0x6b54,
+  0x3c4e,
+  0x6b72,
+  0x6b9f,
+  0x6bbb,
+  0x23a8d,
+  0x21d0b,
+  0x23afa,
+  0x6c4e,
+  0x23cbc,
+  0x6cbf,
+  0x6ccd,
+  0x6c67,
+  0x6d16,
+  0x6d3e,
+  0x6d69,
+  0x6d78,
+  0x6d85,
+  0x23d1e,
+  0x6d34,
+  0x6e2f,
+  0x6e6e,
+  0x3d33,
+  0x6ecb,
+  0x6ec7,
+  0x23ed1,
+  0x6df9,
+  0x6f6e,
+  0x23f5e,
+  0x23f8e,
+  0x6fc6,
+  0x7039,
+  0x701e,
+  0x701b,
+  0x3d96,
+  0x704a,
+  0x707d,
+  0x7077,
+  0x70ad,
+  0x20525,
+  0x7145,
+  0x24263,
+  0x719c,
+  0x243ab,
+  0x7228,
+  0x7235,
+  0x7250,
+  0x24608,
+  0x7280,
+  0x7295,
+  0x24735,
+  0x24814,
+  0x737a,
+  0x738b,
+  0x3eac,
+  0x73a5,
+  0x3eb8,
+  0x7447,
+  0x745c,
+  0x7471,
+  0x7485,
+  0x74ca,
+  0x3f1b,
+  0x7524,
+  0x24c36,
+  0x753e,
+  0x24c92,
+  0x2219f,
+  0x7610,
+  0x24fa1,
+  0x24fb8,
+  0x25044,
+  0x3ffc,
+  0x4008,
+  0x76f4,
+  0x250f3,
+  0x250f2,
+  0x25119,
+  0x25133,
+  0x771e,
+  0x771f,
+  0x774a,
+  0x4039,
+  0x778b,
+  0x4046,
+  0x4096,
+  0x2541d,
+  0x784e,
+  0x78cc,
+  0x40e3,
+  0x25626,
+  0x2569a,
+  0x256c5,
+  0x79eb,
+  0x412f,
+  0x7a4a,
+  0x7a4f,
+  0x2597c,
+  0x25aa7,
+  0x7aee,
+  0x4202,
+  0x25bab,
+  0x7bc6,
+  0x7bc9,
+  0x4227,
+  0x25c80,
+  0x7cd2,
+  0x42a0,
+  0x7ce8,
+  0x7ce3,
+  0x7d00,
+  0x25f86,
+  0x7d63,
+  0x4301,
+  0x7dc7,
+  0x7e02,
+  0x7e45,
+  0x4334,
+  0x26228,
+  0x26247,
+  0x4359,
+  0x262d9,
+  0x7f7a,
+  0x2633e,
+  0x7f95,
+  0x7ffa,
+  0x264da,
+  0x26523,
+  0x8060,
+  0x265a8,
+  0x8070,
+  0x2335f,
+  0x43d5,
+  0x80b2,
+  0x8103,
+  0x440b,
+  0x813e,
+  0x5ab5,
+  0x267a7,
+  0x267b5,
+  0x23393,
+  0x2339c,
+  0x8204,
+  0x8f9e,
+  0x446b,
+  0x8291,
+  0x828b,
+  0x829d,
+  0x52b3,
+  0x82b1,
+  0x82b3,
+  0x82bd,
+  0x82e6,
+  0x26b3c,
+  0x831d,
+  0x8363,
+  0x83ad,
+  0x8323,
+  0x83bd,
+  0x83e7,
+  0x8353,
+  0x83ca,
+  0x83cc,
+  0x83dc,
+  0x26c36,
+  0x26d6b,
+  0x26cd5,
+  0x452b,
+  0x84f1,
+  0x84f3,
+  0x8516,
+  0x273ca,
+  0x8564,
+  0x26f2c,
+  0x455d,
+  0x4561,
+  0x26fb1,
+  0x270d2,
+  0x456b,
+  0x8650,
+  0x8667,
+  0x8669,
+  0x86a9,
+  0x8688,
+  0x870e,
+  0x86e2,
+  0x8779,
+  0x8728,
+  0x876b,
+  0x8786,
+  0x45d7,
+  0x87e1,
+  0x8801,
+  0x45f9,
+  0x8860,
+  0x27667,
+  0x88d7,
+  0x88de,
+  0x4635,
+  0x88fa,
+  0x34bb,
+  0x278ae,
+  0x27966,
+  0x46be,
+  0x46c7,
+  0x8aa0,
+  0x8aed,
+  0x8b8a,
+  0x27ca8,
+  0x8cab,
+  0x8cc1,
+  0x8d1b,
+  0x8d77,
+  0x27f2f,
+  0x20804,
+  0x8dcb,
+  0x8dbc,
+  0x8df0,
+  0x208de,
+  0x8ed4,
+  0x8f38,
+  0x285d2,
+  0x285ed,
+  0x9094,
+  0x90f1,
+  0x9111,
+  0x2872e,
+  0x911b,
+  0x9238,
+  0x92d7,
+  0x92d8,
+  0x927c,
+  0x93f9,
+  0x9415,
+  0x28bfa,
+  0x958b,
+  0x4995,
+  0x95b7,
+  0x28d77,
+  0x49e6,
+  0x96c3,
+  0x5db2,
+  0x9723,
+  0x29145,
+  0x2921a,
+  0x4a6e,
+  0x4a76,
+  0x97e0,
+  0x2940a,
+  0x4ab2,
+  0x29496,
+  0x980b,
+  0x9829,
+  0x295b6,
+  0x98e2,
+  0x4b33,
+  0x9929,
+  0x99a7,
+  0x99c2,
+  0x99fe,
+  0x4bce,
+  0x29b30,
+  0x9b12,
+  0x9c40,
+  0x9cfd,
+  0x4cce,
+  0x4ced,
+  0x9d67,
+  0x2a0ce,
+  0x4cf8,
+  0x2a105,
+  0x2a20e,
+  0x2a291,
+  0x4d56,
+  0x9efe,
+  0x9f05,
+  0x9f0f,
+  0x9f16,
+  0x2a600,
+};
+
+const struct canon_node _wind_canon_table[] = {
+  {0x0, 0, 3, 0},
+  {0x0, 0, 10, 3},
+  {0x0, 0, 16, 13},
+  {0x0, 0, 15, 29},
+  {0x0, 1, 14, 44},
+  {0x2f993, 16, 16, 57},
+  {0x0, 0, 16, 57},
+  {0x0, 0, 16, 73},
+  {0x0, 8, 16, 89},
+  {0xf942, 16, 16, 97},
+  {0x2f994, 16, 16, 97},
+  {0x0, 0, 16, 97},
+  {0x0, 9, 15, 113},
+  {0x0, 5, 6, 119},
+  {0x2f9ef, 16, 16, 120},
+  {0x0, 0, 16, 120},
+  {0x0, 0, 16, 136},
+  {0x0, 0, 16, 152},
+  {0x0, 0, 1, 168},
+  {0x0, 0, 1, 169},
+  {0x0, 3, 4, 170},
+  {0x0, 4, 5, 171},
+  {0x0, 5, 6, 172},
+  {0x1f94, 16, 16, 173},
+  {0x0, 0, 16, 173},
+  {0x0, 0, 12, 189},
+  {0x0, 10, 12, 201},
+  {0x2f8f6, 16, 16, 203},
+  {0xf970, 16, 16, 203},
+  {0x0, 0, 16, 203},
+  {0x0, 2, 14, 219},
+  {0x0, 2, 6, 231},
+  {0x0, 0, 1, 235},
+  {0x0, 0, 1, 236},
+  {0x0, 6, 7, 237},
+  {0x0, 5, 6, 238},
+  {0x0, 4, 5, 239},
+  {0x6c0, 16, 16, 240},
+  {0x0, 0, 16, 240},
+  {0x0, 0, 13, 256},
+  {0x0, 9, 10, 269},
+  {0xf9ae, 16, 16, 270},
+  {0x0, 0, 16, 270},
+  {0x0, 2, 16, 286},
+  {0x0, 15, 16, 300},
+  {0xfa69, 16, 16, 301},
+  {0x0, 0, 11, 301},
+  {0x0, 1, 16, 312},
+  {0x0, 3, 14, 327},
+  {0x0, 6, 7, 338},
+  {0x2f9a4, 16, 16, 339},
+  {0x0, 4, 15, 339},
+  {0x0, 9, 10, 350},
+  {0xf9be, 16, 16, 351},
+  {0x0, 1, 12, 351},
+  {0x0, 7, 8, 362},
+  {0x2f864, 16, 16, 363},
+  {0x0, 0, 13, 363},
+  {0x0, 0, 1, 376},
+  {0x0, 0, 1, 377},
+  {0x0, 3, 4, 378},
+  {0x0, 4, 5, 379},
+  {0x0, 5, 6, 380},
+  {0x1fc2, 16, 16, 381},
+  {0x0, 0, 16, 381},
+  {0x0, 0, 16, 397},
+  {0x0, 1, 16, 413},
+  {0x0, 0, 1, 428},
+  {0x0, 3, 4, 429},
+  {0x0, 0, 1, 430},
+  {0x0, 9, 10, 431},
+  {0x0, 9, 10, 432},
+  {0x3065, 16, 16, 433},
+  {0x0, 0, 3, 433},
+  {0x0, 0, 12, 436},
+  {0x0, 3, 14, 448},
+  {0x0, 0, 1, 459},
+  {0x0, 0, 1, 460},
+  {0x0, 3, 4, 461},
+  {0x0, 3, 4, 462},
+  {0x0, 8, 9, 463},
+  {0x2244, 16, 16, 464},
+  {0x0, 0, 15, 464},
+  {0x0, 0, 12, 479},
+  {0x0, 0, 1, 491},
+  {0x0, 0, 1, 492},
+  {0x0, 3, 4, 493},
+  {0x0, 0, 1, 494},
+  {0x0, 8, 9, 495},
+  {0x1e7b, 16, 16, 496},
+  {0x0, 1, 16, 496},
+  {0x0, 0, 1, 511},
+  {0x0, 3, 4, 512},
+  {0x0, 0, 1, 513},
+  {0x0, 9, 10, 514},
+  {0x0, 9, 10, 515},
+  {0x30ba, 16, 16, 516},
+  {0x2f995, 16, 16, 516},
+  {0x0, 0, 15, 516},
+  {0x0, 0, 15, 531},
+  {0x0, 0, 1, 546},
+  {0x0, 0, 1, 547},
+  {0x0, 3, 4, 548},
+  {0x0, 0, 1, 549},
+  {0x0, 8, 9, 550},
+  {0x4df, 16, 16, 551},
+  {0x0, 0, 16, 551},
+  {0x0, 7, 8, 567},
+  {0x2f9d7, 16, 16, 568},
+  {0x0, 0, 16, 568},
+  {0x0, 14, 15, 584},
+  {0x2f86b, 16, 16, 585},
+  {0xf94a, 16, 16, 585},
+  {0x0, 4, 14, 585},
+  {0x0, 9, 13, 595},
+  {0x0, 0, 1, 599},
+  {0x0, 0, 1, 600},
+  {0x0, 13, 14, 601},
+  {0x0, 12, 13, 602},
+  {0x0, 10, 11, 603},
+  {0xddd, 16, 16, 604},
+  {0x0, 2, 16, 604},
+  {0x0, 1, 15, 618},
+  {0xf91a, 16, 16, 632},
+  {0x0, 0, 16, 632},
+  {0x0, 1, 4, 648},
+  {0x0, 9, 10, 651},
+  {0x2f943, 16, 16, 652},
+  {0x0, 0, 16, 652},
+  {0x0, 10, 11, 668},
+  {0x0, 8, 9, 669},
+  {0x2f9d3, 16, 16, 670},
+  {0x0, 3, 16, 670},
+  {0x0, 1, 16, 683},
+  {0x0, 0, 1, 698},
+  {0x0, 0, 1, 699},
+  {0x0, 3, 4, 700},
+  {0x0, 0, 3, 701},
+  {0x0, 1, 13, 704},
+  {0x10c, 16, 16, 716},
+  {0x0, 1, 16, 716},
+  {0x0, 1, 2, 731},
+  {0xf958, 16, 16, 732},
+  {0x0, 0, 1, 732},
+  {0x0, 0, 1, 733},
+  {0x0, 3, 4, 734},
+  {0x0, 0, 1, 735},
+  {0x0, 0, 9, 736},
+  {0x4e5, 16, 16, 745},
+  {0x439, 16, 16, 745},
+  {0x4e3, 16, 16, 745},
+  {0x0, 2, 15, 745},
+  {0x0, 12, 13, 758},
+  {0x2f8c7, 16, 16, 759},
+  {0x0, 0, 1, 759},
+  {0x0, 3, 4, 760},
+  {0x0, 0, 1, 761},
+  {0x0, 9, 10, 762},
+  {0x0, 9, 10, 763},
+  {0x30b4, 16, 16, 764},
+  {0x45d, 16, 16, 764},
+  {0x0, 0, 16, 764},
+  {0x0, 0, 1, 780},
+  {0x0, 0, 1, 781},
+  {0x0, 3, 4, 782},
+  {0x0, 0, 3, 783},
+  {0x0, 0, 10, 786},
+  {0x1ee8, 16, 16, 796},
+  {0x0, 0, 16, 796},
+  {0x0, 0, 1, 812},
+  {0x0, 0, 1, 813},
+  {0x0, 3, 4, 814},
+  {0x0, 0, 4, 815},
+  {0x0, 3, 14, 819},
+  {0x1eb9, 16, 16, 830},
+  {0x1eee, 16, 16, 830},
+  {0x229, 16, 16, 830},
+  {0x1eec, 16, 16, 830},
+  {0x119, 16, 16, 830},
+  {0x2fa07, 16, 16, 830},
+  {0x10a, 16, 16, 830},
+  {0x106, 16, 16, 830},
+  {0x108, 16, 16, 830},
+  {0x0, 1, 16, 830},
+  {0x0, 9, 10, 845},
+  {0x2f90e, 16, 16, 846},
+  {0x0, 0, 14, 846},
+  {0x0, 1, 16, 860},
+  {0x0, 0, 1, 875},
+  {0x0, 0, 1, 876},
+  {0x0, 3, 4, 877},
+  {0x0, 0, 2, 878},
+  {0x0, 4, 5, 880},
+  {0x1f59, 16, 16, 881},
+  {0x0, 6, 12, 881},
+  {0x0, 14, 15, 887},
+  {0x2f9f8, 16, 16, 888},
+  {0x0, 0, 11, 888},
+  {0x0, 0, 1, 899},
+  {0x0, 0, 1, 900},
+  {0x0, 3, 4, 901},
+  {0x0, 0, 4, 902},
+  {0x0, 1, 2, 906},
+  {0x212, 16, 16, 907},
+  {0x0, 0, 1, 907},
+  {0x0, 0, 1, 908},
+  {0x0, 3, 4, 909},
+  {0x0, 0, 3, 910},
+  {0x0, 1, 12, 913},
+  {0x20f, 16, 16, 924},
+  {0x0, 2, 14, 924},
+  {0x0, 0, 1, 936},
+  {0x0, 0, 1, 937},
+  {0x0, 3, 4, 938},
+  {0x0, 3, 4, 939},
+  {0x0, 8, 9, 940},
+  {0x22e1, 16, 16, 941},
+  {0x0, 0, 15, 941},
+  {0x0, 13, 14, 956},
+  {0xf967, 16, 16, 957},
+  {0x1e19, 16, 16, 957},
+  {0x0, 1, 16, 957},
+  {0x0, 10, 11, 972},
+  {0xf9f0, 16, 16, 973},
+  {0x0, 0, 15, 973},
+  {0x0, 2, 3, 988},
+  {0x2f807, 16, 16, 989},
+  {0x0, 3, 15, 989},
+  {0x0, 13, 14, 1001},
+  {0x2f8b9, 16, 16, 1002},
+  {0x0, 0, 1, 1002},
+  {0x0, 0, 1, 1003},
+  {0x0, 3, 4, 1004},
+  {0x0, 0, 4, 1005},
+  {0x0, 0, 16, 1009},
+  {0x1d0, 16, 16, 1025},
+  {0x0, 0, 14, 1025},
+  {0x0, 9, 10, 1039},
+  {0x2f974, 16, 16, 1040},
+  {0x0, 1, 12, 1040},
+  {0x0, 1, 5, 1051},
+  {0x0, 5, 6, 1055},
+  {0x2f91b, 16, 16, 1056},
+  {0x0, 0, 1, 1056},
+  {0x0, 0, 1, 1057},
+  {0x0, 3, 4, 1058},
+  {0x0, 3, 4, 1059},
+  {0x0, 8, 9, 1060},
+  {0x22e0, 16, 16, 1061},
+  {0x0, 0, 16, 1061},
+  {0x0, 1, 11, 1077},
+  {0x2f82e, 16, 16, 1087},
+  {0x0, 0, 16, 1087},
+  {0x0, 0, 1, 1103},
+  {0x0, 0, 1, 1104},
+  {0x0, 3, 4, 1105},
+  {0x0, 0, 2, 1106},
+  {0x0, 3, 5, 1108},
+  {0x1f19, 16, 16, 1110},
+  {0x0, 0, 10, 1110},
+  {0x0, 9, 10, 1120},
+  {0x2f8ce, 16, 16, 1121},
+  {0x1f18, 16, 16, 1121},
+  {0x0, 1, 15, 1121},
+  {0x1f7d, 0, 1, 1135},
+  {0x0, 0, 1, 1136},
+  {0x0, 3, 4, 1137},
+  {0x0, 4, 5, 1138},
+  {0x0, 5, 6, 1139},
+  {0x1ff4, 16, 16, 1140},
+  {0x0, 0, 16, 1140},
+  {0x0, 9, 10, 1156},
+  {0xf9dd, 16, 16, 1157},
+  {0x0, 1, 14, 1157},
+  {0x2f991, 16, 16, 1170},
+  {0x0, 2, 16, 1170},
+  {0x0, 3, 4, 1184},
+  {0xfa0b, 16, 16, 1185},
+  {0x0, 6, 16, 1185},
+  {0x0, 0, 1, 1195},
+  {0x0, 0, 1, 1196},
+  {0x0, 3, 4, 1197},
+  {0x0, 0, 5, 1198},
+  {0x0, 2, 3, 1203},
+  {0x1fcf, 16, 16, 1204},
+  {0x0, 0, 15, 1204},
+  {0x0, 8, 9, 1219},
+  {0x2f9bc, 16, 16, 1220},
+  {0x0, 6, 7, 1220},
+  {0x0, 3, 4, 1221},
+  {0x2f838, 16, 16, 1222},
+  {0x0, 0, 7, 1222},
+  {0x0, 9, 10, 1229},
+  {0x0, 2, 3, 1230},
+  {0x2f88f, 16, 16, 1231},
+  {0x0, 2, 6, 1231},
+  {0x0, 0, 1, 1235},
+  {0x0, 0, 1, 1236},
+  {0x0, 3, 4, 1237},
+  {0x0, 3, 4, 1238},
+  {0x0, 8, 9, 1239},
+  {0x22ec, 16, 16, 1240},
+  {0x0, 0, 7, 1240},
+  {0x2f88d, 16, 16, 1247},
+  {0x0, 4, 16, 1247},
+  {0x0, 14, 15, 1259},
+  {0xfa3f, 16, 16, 1260},
+  {0x2f98f, 16, 16, 1260},
+  {0x0, 8, 12, 1260},
+  {0x0, 11, 12, 1264},
+  {0x2f9ee, 16, 16, 1265},
+  {0xfa35, 16, 16, 1265},
+  {0x0, 0, 1, 1265},
+  {0x0, 0, 1, 1266},
+  {0x0, 3, 4, 1267},
+  {0x0, 0, 3, 1268},
+  {0x0, 1, 2, 1271},
+  {0x203, 16, 16, 1272},
+  {0x0, 6, 8, 1272},
+  {0x0, 0, 1, 1274},
+  {0x0, 0, 1, 1275},
+  {0x0, 13, 14, 1276},
+  {0x0, 3, 6, 1277},
+  {0x0, 7, 8, 1280},
+  {0xd4c, 16, 16, 1281},
+  {0x0, 0, 15, 1281},
+  {0x0, 2, 3, 1296},
+  {0xfa20, 16, 16, 1297},
+  {0x0, 3, 13, 1297},
+  {0x0, 0, 2, 1307},
+  {0x0, 0, 1, 1309},
+  {0x0, 0, 1, 1310},
+  {0x0, 3, 4, 1311},
+  {0x0, 0, 1, 1312},
+  {0x0, 2, 7, 1313},
+  {0x1eac, 16, 16, 1318},
+  {0x0, 0, 16, 1318},
+  {0x0, 3, 4, 1334},
+  {0x2f874, 16, 16, 1335},
+  {0x1eb6, 16, 16, 1335},
+  {0x0, 0, 1, 1335},
+  {0x0, 0, 1, 1336},
+  {0x0, 3, 4, 1337},
+  {0x0, 4, 5, 1338},
+  {0x0, 5, 6, 1339},
+  {0x1f9c, 16, 16, 1340},
+  {0x0, 2, 12, 1340},
+  {0x0, 6, 16, 1350},
+  {0x0, 0, 1, 1360},
+  {0x0, 0, 1, 1361},
+  {0x0, 3, 4, 1362},
+  {0x0, 0, 1, 1363},
+  {0x0, 6, 7, 1364},
+  {0x1e1d, 16, 16, 1365},
+  {0x0, 1, 14, 1365},
+  {0x0, 0, 14, 1378},
+  {0x2f918, 16, 16, 1392},
+  {0x0, 2, 14, 1392},
+  {0x0, 9, 10, 1404},
+  {0x2f975, 16, 16, 1405},
+  {0x0, 1, 10, 1405},
+  {0x0, 11, 12, 1414},
+  {0xfa0a, 16, 16, 1415},
+  {0x0, 0, 16, 1415},
+  {0x0, 2, 4, 1431},
+  {0xf992, 16, 16, 1433},
+  {0xfa47, 16, 16, 1433},
+  {0x0, 2, 15, 1433},
+  {0x0, 13, 16, 1446},
+  {0xfa53, 16, 16, 1449},
+  {0xfa52, 16, 16, 1449},
+  {0xfa1b, 16, 16, 1449},
+  {0x0, 0, 1, 1449},
+  {0x0, 3, 4, 1450},
+  {0x0, 0, 1, 1451},
+  {0x0, 9, 10, 1452},
+  {0x0, 9, 10, 1453},
+  {0x30b2, 16, 16, 1454},
+  {0x0, 0, 1, 1454},
+  {0x0, 0, 1, 1455},
+  {0x0, 3, 4, 1456},
+  {0x0, 0, 5, 1457},
+  {0x0, 0, 2, 1462},
+  {0x1fca, 16, 16, 1464},
+  {0x389, 16, 16, 1464},
+  {0x0, 1, 16, 1464},
+  {0x0, 12, 13, 1479},
+  {0x2f93e, 16, 16, 1480},
+  {0x0, 3, 15, 1480},
+  {0x0, 3, 9, 1492},
+  {0x2f968, 16, 16, 1498},
+  {0x0, 0, 1, 1498},
+  {0x0, 0, 1, 1499},
+  {0x0, 3, 4, 1500},
+  {0x0, 0, 5, 1501},
+  {0x0, 2, 6, 1506},
+  {0x1f2e, 16, 16, 1510},
+  {0x1f98, 16, 16, 1510},
+  {0x0, 6, 12, 1510},
+  {0x0, 0, 1, 1516},
+  {0x2f804, 16, 16, 1517},
+  {0x2f919, 16, 16, 1517},
+  {0x2f835, 16, 16, 1517},
+  {0x0, 1, 2, 1517},
+  {0x0, 5, 6, 1518},
+  {0x2f824, 16, 16, 1519},
+  {0x0, 0, 16, 1519},
+  {0x1fe3, 16, 16, 1535},
+  {0x0, 2, 4, 1535},
+  {0x0, 0, 1, 1537},
+  {0x0, 0, 1, 1538},
+  {0x0, 3, 4, 1539},
+  {0x0, 0, 1, 1540},
+  {0x0, 7, 8, 1541},
+  {0x1e69, 16, 16, 1542},
+  {0x1fbe, 0, 1, 1542},
+  {0x0, 0, 16, 1543},
+  {0x0, 3, 4, 1559},
+  {0x2f96c, 16, 16, 1560},
+  {0x0, 0, 15, 1560},
+  {0x0, 10, 11, 1575},
+  {0x2f85d, 16, 16, 1576},
+  {0x0, 3, 11, 1576},
+  {0x2f836, 16, 16, 1584},
+  {0x0, 12, 13, 1584},
+  {0x2f92f, 16, 16, 1585},
+  {0x0, 0, 10, 1585},
+  {0x0, 0, 1, 1595},
+  {0x0, 0, 1, 1596},
+  {0x0, 3, 4, 1597},
+  {0x0, 0, 5, 1598},
+  {0x0, 2, 3, 1603},
+  {0x1f5f, 16, 16, 1604},
+  {0x0, 2, 3, 1604},
+  {0x0, 15, 16, 1605},
+  {0x2f9d8, 16, 16, 1606},
+  {0x0, 1, 16, 1606},
+  {0x0, 0, 12, 1621},
+  {0xf932, 16, 16, 1633},
+  {0x0, 0, 16, 1633},
+  {0x0, 11, 12, 1649},
+  {0xfa6a, 16, 16, 1650},
+  {0x0, 2, 16, 1650},
+  {0x0, 2, 4, 1664},
+  {0xfa68, 16, 16, 1666},
+  {0x0, 2, 16, 1666},
+  {0x212b, 0, 1, 1680},
+  {0x0, 0, 1, 1681},
+  {0x0, 3, 4, 1682},
+  {0x0, 0, 1, 1683},
+  {0x0, 1, 2, 1684},
+  {0x1fa, 16, 16, 1685},
+  {0x0, 1, 16, 1685},
+  {0x0, 0, 1, 1700},
+  {0x0, 3, 4, 1701},
+  {0x0, 0, 1, 1702},
+  {0x0, 9, 10, 1703},
+  {0x0, 9, 10, 1704},
+  {0x30c9, 16, 16, 1705},
+  {0xf9ea, 16, 16, 1705},
+  {0x0, 2, 16, 1705},
+  {0x0, 0, 1, 1719},
+  {0x0, 0, 1, 1720},
+  {0x0, 3, 4, 1721},
+  {0x0, 0, 1, 1722},
+  {0x0, 1, 2, 1723},
+  {0x1e09, 16, 16, 1724},
+  {0x0, 1, 11, 1724},
+  {0x0, 2, 3, 1734},
+  {0x2f8e1, 16, 16, 1735},
+  {0x0, 0, 14, 1735},
+  {0x0, 0, 1, 1749},
+  {0x0, 3, 4, 1750},
+  {0x0, 0, 1, 1751},
+  {0x0, 9, 10, 1752},
+  {0x0, 9, 10, 1753},
+  {0x30f9, 16, 16, 1754},
+  {0x0, 13, 14, 1754},
+  {0xf986, 16, 16, 1755},
+  {0x0, 0, 1, 1755},
+  {0x0, 0, 1, 1756},
+  {0x0, 3, 4, 1757},
+  {0x0, 0, 4, 1758},
+  {0x0, 7, 8, 1762},
+  {0x1e03, 16, 16, 1763},
+  {0x0, 0, 1, 1763},
+  {0x0, 0, 1, 1764},
+  {0x0, 3, 4, 1765},
+  {0x0, 0, 1, 1766},
+  {0x0, 1, 5, 1767},
+  {0x1fd, 16, 16, 1771},
+  {0x0, 0, 1, 1771},
+  {0x0, 0, 1, 1772},
+  {0x0, 3, 4, 1773},
+  {0x0, 3, 4, 1774},
+  {0x0, 8, 9, 1775},
+  {0x2281, 16, 16, 1776},
+  {0x1e3, 16, 16, 1776},
+  {0x0, 2, 12, 1776},
+  {0x0, 0, 1, 1786},
+  {0x0, 0, 1, 1787},
+  {0x0, 3, 4, 1788},
+  {0x0, 3, 4, 1789},
+  {0x0, 8, 9, 1790},
+  {0x22af, 16, 16, 1791},
+  {0xf96b, 16, 16, 1791},
+  {0x0, 2, 16, 1791},
+  {0x0, 3, 10, 1805},
+  {0x0, 2, 3, 1812},
+  {0x2f937, 16, 16, 1813},
+  {0x0, 2, 12, 1813},
+  {0x0, 2, 3, 1823},
+  {0xf98d, 16, 16, 1824},
+  {0x0, 6, 16, 1824},
+  {0x0, 0, 1, 1834},
+  {0x0, 3, 4, 1835},
+  {0x0, 0, 1, 1836},
+  {0x0, 9, 10, 1837},
+  {0x0, 9, 10, 1838},
+  {0x30b0, 16, 16, 1839},
+  {0x0, 0, 1, 1839},
+  {0x0, 0, 1, 1840},
+  {0x0, 3, 4, 1841},
+  {0x0, 0, 3, 1842},
+  {0x0, 1, 8, 1845},
+  {0x1e3e, 16, 16, 1852},
+  {0x1e40, 16, 16, 1852},
+  {0x0, 8, 9, 1852},
+  {0xfa65, 16, 16, 1853},
+  {0x0, 6, 16, 1853},
+  {0x0, 10, 11, 1863},
+  {0xf93a, 16, 16, 1864},
+  {0x0, 0, 16, 1864},
+  {0x0, 0, 1, 1880},
+  {0x0, 0, 1, 1881},
+  {0x0, 3, 4, 1882},
+  {0x0, 4, 5, 1883},
+  {0x0, 5, 6, 1884},
+  {0x1faa, 16, 16, 1885},
+  {0x0, 0, 1, 1885},
+  {0x0, 2, 4, 1886},
+  {0x2001, 16, 16, 1888},
+  {0x2000, 16, 16, 1888},
+  {0x0, 0, 16, 1888},
+  {0x0, 11, 12, 1904},
+  {0x0, 8, 9, 1905},
+  {0x2f897, 16, 16, 1906},
+  {0x0, 2, 15, 1906},
+  {0x0, 4, 5, 1919},
+  {0x2f934, 16, 16, 1920},
+  {0x0, 1, 13, 1920},
+  {0x0, 11, 12, 1932},
+  {0x2f848, 16, 16, 1933},
+  {0x0, 0, 16, 1933},
+  {0x0, 0, 1, 1949},
+  {0x0, 0, 1, 1950},
+  {0x0, 3, 4, 1951},
+  {0x0, 0, 5, 1952},
+  {0x0, 2, 6, 1957},
+  {0x1f07, 16, 16, 1961},
+  {0x1f81, 16, 16, 1961},
+  {0x0, 0, 1, 1961},
+  {0x0, 0, 1, 1962},
+  {0x0, 3, 4, 1963},
+  {0x0, 0, 4, 1964},
+  {0x0, 7, 13, 1968},
+  {0x1e0b, 16, 16, 1974},
+  {0x0, 0, 1, 1974},
+  {0x0, 0, 1, 1975},
+  {0x0, 3, 4, 1976},
+  {0x0, 4, 5, 1977},
+  {0x0, 5, 6, 1978},
+  {0x1f9b, 16, 16, 1979},
+  {0x0, 0, 1, 1979},
+  {0x0, 0, 1, 1980},
+  {0x0, 3, 4, 1981},
+  {0x0, 0, 3, 1982},
+  {0x0, 3, 4, 1985},
+  {0x1e43, 16, 16, 1986},
+  {0x0, 8, 9, 1986},
+  {0x0, 0, 1, 1987},
+  {0x0, 0, 1, 1988},
+  {0x0, 3, 4, 1989},
+  {0x0, 0, 5, 1990},
+  {0x0, 0, 2, 1995},
+  {0x1fed, 16, 16, 1997},
+  {0x385, 16, 16, 1997},
+  {0x0, 2, 4, 1997},
+  {0x0, 0, 1, 1999},
+  {0x0, 0, 1, 2000},
+  {0x0, 3, 4, 2001},
+  {0x0, 0, 1, 2002},
+  {0x0, 0, 2, 2003},
+  {0x1e17, 16, 16, 2005},
+  {0x0, 1, 15, 2005},
+  {0x0, 14, 15, 2019},
+  {0x2f95f, 16, 16, 2020},
+  {0x0, 0, 1, 2020},
+  {0x0, 0, 1, 2021},
+  {0x0, 3, 4, 2022},
+  {0x0, 0, 5, 2023},
+  {0x0, 0, 2, 2028},
+  {0x1f53, 16, 16, 2030},
+  {0x1f55, 16, 16, 2030},
+  {0x0, 0, 1, 2030},
+  {0x0, 0, 1, 2031},
+  {0x0, 3, 4, 2032},
+  {0x0, 3, 4, 2033},
+  {0x0, 8, 9, 2034},
+  {0x22ad, 16, 16, 2035},
+  {0x0, 2, 12, 2035},
+  {0x0, 0, 1, 2045},
+  {0x0, 3, 4, 2046},
+  {0x0, 0, 1, 2047},
+  {0x0, 9, 10, 2048},
+  {0x0, 9, 11, 2049},
+  {0x3079, 16, 16, 2051},
+  {0x0, 0, 1, 2051},
+  {0x0, 3, 4, 2052},
+  {0x0, 0, 1, 2053},
+  {0x0, 9, 10, 2054},
+  {0x0, 9, 11, 2055},
+  {0x307d, 16, 16, 2057},
+  {0x0, 3, 8, 2057},
+  {0x1e5a, 16, 16, 2062},
+  {0x156, 16, 16, 2062},
+  {0x0, 12, 13, 2062},
+  {0xf982, 16, 16, 2063},
+  {0x0, 10, 12, 2063},
+  {0x0, 0, 1, 2065},
+  {0x0, 0, 1, 2066},
+  {0x0, 3, 4, 2067},
+  {0x0, 0, 1, 2068},
+  {0x0, 4, 5, 2069},
+  {0x1ec, 16, 16, 2070},
+  {0x0, 4, 14, 2070},
+  {0x0, 3, 4, 2080},
+  {0xfa64, 16, 16, 2081},
+  {0x0, 0, 1, 2081},
+  {0x0, 0, 1, 2082},
+  {0x0, 3, 4, 2083},
+  {0x0, 4, 5, 2084},
+  {0x0, 5, 6, 2085},
+  {0x1f8e, 16, 16, 2086},
+  {0x0, 7, 8, 2086},
+  {0xf99c, 16, 16, 2087},
+  {0x0, 0, 10, 2087},
+  {0x0, 0, 1, 2097},
+  {0x0, 0, 1, 2098},
+  {0x0, 3, 4, 2099},
+  {0x0, 0, 5, 2100},
+  {0x0, 0, 2, 2105},
+  {0x1f3d, 16, 16, 2107},
+  {0x0, 0, 1, 2107},
+  {0x0, 3, 4, 2108},
+  {0x0, 0, 5, 2109},
+  {0x0, 2, 3, 2114},
+  {0x1fd6, 16, 16, 2115},
+  {0x0, 6, 15, 2115},
+  {0x0, 0, 1, 2124},
+  {0x0, 0, 1, 2125},
+  {0x0, 3, 4, 2126},
+  {0x0, 0, 5, 2127},
+  {0x0, 0, 2, 2132},
+  {0x1fde, 16, 16, 2134},
+  {0x1fdd, 16, 16, 2134},
+  {0x0, 0, 1, 2134},
+  {0x0, 0, 1, 2135},
+  {0x0, 3, 4, 2136},
+  {0x0, 4, 5, 2137},
+  {0x0, 5, 6, 2138},
+  {0x1f95, 16, 16, 2139},
+  {0x0, 4, 8, 2139},
+  {0xf90b, 16, 16, 2143},
+  {0x2f846, 16, 16, 2143},
+  {0x0, 3, 6, 2143},
+  {0x0, 0, 1, 2146},
+  {0x0, 0, 1, 2147},
+  {0x0, 3, 4, 2148},
+  {0x0, 3, 4, 2149},
+  {0x0, 8, 9, 2150},
+  {0x2224, 16, 16, 2151},
+  {0x0, 0, 16, 2151},
+  {0x0, 12, 13, 2167},
+  {0xfa08, 16, 16, 2168},
+  {0x0, 5, 6, 2168},
+  {0x2f905, 16, 16, 2169},
+  {0x0, 10, 11, 2169},
+  {0xf995, 16, 16, 2170},
+  {0x0, 0, 1, 2170},
+  {0x0, 3, 4, 2171},
+  {0x0, 0, 1, 2172},
+  {0x0, 9, 10, 2173},
+  {0x0, 9, 10, 2174},
+  {0x30c7, 16, 16, 2175},
+  {0x0, 0, 1, 2175},
+  {0x0, 0, 1, 2176},
+  {0x0, 3, 4, 2177},
+  {0x0, 0, 5, 2178},
+  {0x0, 0, 2, 2183},
+  {0x1f22, 16, 16, 2185},
+  {0x0, 5, 11, 2185},
+  {0xf97f, 16, 16, 2191},
+  {0x0, 9, 10, 2191},
+  {0x2fa00, 16, 16, 2192},
+  {0x0, 7, 16, 2192},
+  {0x0, 2, 11, 2201},
+  {0xf9e6, 16, 16, 2210},
+  {0x0, 1, 16, 2210},
+  {0x0, 10, 11, 2225},
+  {0xfa17, 16, 16, 2226},
+  {0xfa5a, 16, 16, 2226},
+  {0x0, 10, 12, 2226},
+  {0x0, 0, 1, 2228},
+  {0x0, 0, 1, 2229},
+  {0x0, 3, 4, 2230},
+  {0x0, 0, 1, 2231},
+  {0x0, 4, 5, 2232},
+  {0x1e5d, 16, 16, 2233},
+  {0x0, 7, 10, 2233},
+  {0x2f9b5, 16, 16, 2236},
+  {0x2f9b6, 16, 16, 2236},
+  {0x0, 0, 12, 2236},
+  {0x0, 0, 16, 2248},
+  {0xf997, 16, 16, 2264},
+  {0x0, 1, 12, 2264},
+  {0x0, 11, 12, 2275},
+  {0x0, 6, 7, 2276},
+  {0x2fa01, 16, 16, 2277},
+  {0x0, 10, 16, 2277},
+  {0x0, 8, 15, 2283},
+  {0xfa22, 16, 16, 2290},
+  {0x0, 0, 10, 2290},
+  {0x0, 0, 1, 2300},
+  {0x0, 0, 1, 2301},
+  {0x0, 3, 4, 2302},
+  {0x0, 0, 1, 2303},
+  {0x0, 0, 2, 2304},
+  {0x1f4a, 16, 16, 2306},
+  {0x0, 4, 13, 2306},
+  {0x0, 6, 7, 2315},
+  {0x0, 0, 1, 2316},
+  {0x0, 0, 1, 2317},
+  {0x0, 12, 13, 2318},
+  {0x0, 5, 6, 2319},
+  {0x0, 6, 7, 2320},
+  {0xc48, 16, 16, 2321},
+  {0x2f976, 16, 16, 2321},
+  {0x0, 15, 16, 2321},
+  {0xf97c, 16, 16, 2322},
+  {0x0, 2, 13, 2322},
+  {0x0, 4, 5, 2333},
+  {0xf930, 16, 16, 2334},
+  {0x212a, 0, 1, 2334},
+  {0x0, 0, 1, 2335},
+  {0x0, 3, 4, 2336},
+  {0x0, 0, 4, 2337},
+  {0x0, 1, 2, 2341},
+  {0x1e34, 16, 16, 2342},
+  {0x0, 2, 11, 2342},
+  {0x0, 3, 4, 2351},
+  {0x2f97c, 16, 16, 2352},
+  {0x0, 2, 3, 2352},
+  {0x2f85f, 16, 16, 2353},
+  {0x0, 0, 1, 2353},
+  {0x0, 0, 1, 2354},
+  {0x0, 3, 4, 2355},
+  {0x0, 0, 1, 2356},
+  {0x0, 6, 9, 2357},
+  {0x4d1, 16, 16, 2360},
+  {0x0, 1, 2, 2360},
+  {0xfa55, 16, 16, 2361},
+  {0x0, 5, 14, 2361},
+  {0x0, 15, 16, 2370},
+  {0x0, 10, 11, 2371},
+  {0x2f9ed, 16, 16, 2372},
+  {0x2f97d, 16, 16, 2372},
+  {0x0, 9, 10, 2372},
+  {0xf90e, 16, 16, 2373},
+  {0x0, 0, 1, 2373},
+  {0x0, 0, 1, 2374},
+  {0x0, 3, 4, 2375},
+  {0x0, 0, 5, 2376},
+  {0x0, 0, 2, 2381},
+  {0x1f0a, 16, 16, 2383},
+  {0x1f0c, 16, 16, 2383},
+  {0x0, 0, 1, 2383},
+  {0x0, 0, 1, 2384},
+  {0x0, 3, 4, 2385},
+  {0x0, 0, 5, 2386},
+  {0x0, 2, 6, 2391},
+  {0x1f67, 16, 16, 2395},
+  {0x0, 0, 1, 2395},
+  {0x0, 0, 1, 2396},
+  {0x0, 3, 4, 2397},
+  {0x0, 0, 3, 2398},
+  {0x0, 7, 8, 2401},
+  {0xe7, 16, 16, 2402},
+  {0x1fa1, 16, 16, 2402},
+  {0x1eea, 16, 16, 2402},
+  {0x0, 5, 11, 2402},
+  {0x2f978, 16, 16, 2408},
+  {0x0, 2, 3, 2408},
+  {0x0, 0, 1, 2409},
+  {0x0, 0, 1, 2410},
+  {0x0, 3, 4, 2411},
+  {0x0, 0, 1, 2412},
+  {0x0, 1, 9, 2413},
+  {0x3d4, 16, 16, 2421},
+  {0x0, 4, 14, 2421},
+  {0x0, 12, 13, 2431},
+  {0x2f91e, 16, 16, 2432},
+  {0x3d3, 16, 16, 2432},
+  {0x0, 3, 14, 2432},
+  {0x0, 7, 9, 2443},
+  {0x2f9e9, 16, 16, 2445},
+  {0x0, 0, 1, 2445},
+  {0x0, 0, 1, 2446},
+  {0x0, 3, 4, 2447},
+  {0x0, 0, 3, 2448},
+  {0x0, 0, 10, 2451},
+  {0x176, 16, 16, 2461},
+  {0xdd, 16, 16, 2461},
+  {0x1ef2, 16, 16, 2461},
+  {0x1e8e, 16, 16, 2461},
+  {0x232, 16, 16, 2461},
+  {0x0, 6, 16, 2461},
+  {0x0, 0, 1, 2471},
+  {0x0, 3, 4, 2472},
+  {0x0, 0, 1, 2473},
+  {0x0, 9, 10, 2474},
+  {0x0, 9, 10, 2475},
+  {0x3094, 16, 16, 2476},
+  {0x1ef6, 16, 16, 2476},
+  {0x178, 16, 16, 2476},
+  {0x0, 0, 1, 2476},
+  {0x0, 0, 1, 2477},
+  {0x0, 3, 4, 2478},
+  {0x0, 0, 1, 2479},
+  {0x0, 7, 8, 2480},
+  {0x1e68, 16, 16, 2481},
+  {0x2f9e8, 16, 16, 2481},
+  {0x0, 13, 14, 2481},
+  {0x2f999, 16, 16, 2482},
+  {0x0, 0, 1, 2482},
+  {0x0, 0, 1, 2483},
+  {0x0, 3, 4, 2484},
+  {0x0, 0, 3, 2485},
+  {0x0, 0, 9, 2488},
+  {0x1e82, 16, 16, 2497},
+  {0x0, 4, 16, 2497},
+  {0x0, 14, 15, 2509},
+  {0x2f94e, 16, 16, 2510},
+  {0x174, 16, 16, 2510},
+  {0x1e86, 16, 16, 2510},
+  {0x0, 0, 1, 2510},
+  {0x0, 0, 1, 2511},
+  {0x0, 3, 4, 2512},
+  {0x0, 0, 1, 2513},
+  {0x0, 4, 5, 2514},
+  {0x1de, 16, 16, 2515},
+  {0xf9af, 16, 16, 2515},
+  {0x0, 2, 15, 2515},
+  {0x0, 3, 4, 2528},
+  {0x2f89b, 16, 16, 2529},
+  {0x0, 3, 5, 2529},
+  {0x1f28, 16, 16, 2531},
+  {0x1f29, 16, 16, 2531},
+  {0x0, 8, 16, 2531},
+  {0x0, 10, 11, 2539},
+  {0x2f8f9, 16, 16, 2540},
+  {0x0, 10, 11, 2540},
+  {0x2f89c, 16, 16, 2541},
+  {0x0, 1, 2, 2541},
+  {0x1e07, 16, 16, 2542},
+  {0x0, 0, 1, 2542},
+  {0x0, 3, 4, 2543},
+  {0x0, 0, 1, 2544},
+  {0x0, 9, 10, 2545},
+  {0x0, 9, 11, 2546},
+  {0x30d0, 16, 16, 2548},
+  {0x0, 11, 12, 2548},
+  {0x2f9d6, 16, 16, 2549},
+  {0x0, 0, 13, 2549},
+  {0x0, 0, 15, 2562},
+  {0xfa3c, 16, 16, 2577},
+  {0x0, 7, 8, 2577},
+  {0x2f92e, 16, 16, 2578},
+  {0x0, 0, 1, 2578},
+  {0x0, 3, 4, 2579},
+  {0x0, 0, 1, 2580},
+  {0x0, 9, 10, 2581},
+  {0x0, 9, 10, 2582},
+  {0x30ae, 16, 16, 2583},
+  {0x0, 1, 16, 2583},
+  {0x0, 0, 1, 2598},
+  {0x0, 3, 4, 2599},
+  {0x0, 0, 1, 2600},
+  {0x0, 9, 10, 2601},
+  {0x0, 9, 10, 2602},
+  {0x3058, 16, 16, 2603},
+  {0x0, 0, 1, 2603},
+  {0x0, 0, 1, 2604},
+  {0x0, 3, 4, 2605},
+  {0x0, 0, 4, 2606},
+  {0x0, 0, 16, 2610},
+  {0xcb, 16, 16, 2626},
+  {0x1eba, 16, 16, 2626},
+  {0xca, 16, 16, 2626},
+  {0x1ebc, 16, 16, 2626},
+  {0xc8, 16, 16, 2626},
+  {0xc9, 16, 16, 2626},
+  {0x114, 16, 16, 2626},
+  {0x116, 16, 16, 2626},
+  {0x112, 16, 16, 2626},
+  {0xf94b, 16, 16, 2626},
+  {0x2f877, 16, 16, 2626},
+  {0xf9df, 16, 16, 2626},
+  {0xfa3b, 16, 16, 2626},
+  {0x0, 0, 1, 2626},
+  {0x0, 0, 1, 2627},
+  {0x0, 3, 4, 2628},
+  {0x0, 0, 1, 2629},
+  {0x0, 6, 7, 2630},
+  {0x1e1c, 16, 16, 2631},
+  {0x0, 4, 16, 2631},
+  {0x0, 4, 5, 2643},
+  {0x2f93d, 16, 16, 2644},
+  {0x0, 0, 1, 2644},
+  {0x0, 0, 1, 2645},
+  {0x0, 3, 4, 2646},
+  {0x0, 0, 1, 2647},
+  {0x0, 1, 2, 2648},
+  {0x1fb, 16, 16, 2649},
+  {0x0, 6, 7, 2649},
+  {0x0, 13, 14, 2650},
+  {0x2f8e3, 16, 16, 2651},
+  {0x0, 2, 8, 2651},
+  {0x2f85b, 16, 16, 2657},
+  {0x2f85a, 16, 16, 2657},
+  {0x307c, 16, 16, 2657},
+  {0x0, 0, 1, 2657},
+  {0x0, 0, 1, 2658},
+  {0x0, 3, 4, 2659},
+  {0x0, 0, 5, 2660},
+  {0x0, 2, 6, 2665},
+  {0x1f06, 16, 16, 2669},
+  {0x11a, 16, 16, 2669},
+  {0x204, 16, 16, 2669},
+  {0x1f80, 16, 16, 2669},
+  {0x307a, 16, 16, 2669},
+  {0x0, 0, 1, 2669},
+  {0x0, 8, 9, 2670},
+  {0x2f923, 16, 16, 2671},
+  {0x0, 3, 4, 2671},
+  {0x2f944, 16, 16, 2672},
+  {0x0, 10, 11, 2672},
+  {0xf94d, 16, 16, 2673},
+  {0x0, 3, 4, 2673},
+  {0x1ef0, 16, 16, 2674},
+  {0x0, 11, 12, 2674},
+  {0xf9d4, 16, 16, 2675},
+  {0x0, 0, 16, 2675},
+  {0x113, 16, 16, 2691},
+  {0x115, 16, 16, 2691},
+  {0x117, 16, 16, 2691},
+  {0xe8, 16, 16, 2691},
+  {0xe9, 16, 16, 2691},
+  {0xea, 16, 16, 2691},
+  {0x1ebd, 16, 16, 2691},
+  {0x0, 0, 1, 2691},
+  {0x0, 0, 1, 2692},
+  {0x0, 3, 4, 2693},
+  {0x0, 0, 1, 2694},
+  {0x0, 1, 2, 2695},
+  {0x1e08, 16, 16, 2696},
+  {0xeb, 16, 16, 2696},
+  {0x1ebb, 16, 16, 2696},
+  {0x0, 12, 14, 2696},
+  {0x0, 0, 1, 2698},
+  {0x0, 0, 1, 2699},
+  {0x0, 3, 4, 2700},
+  {0x0, 0, 1, 2701},
+  {0x0, 0, 2, 2702},
+  {0x1e52, 16, 16, 2704},
+  {0x0, 9, 14, 2704},
+  {0x0, 0, 5, 2709},
+  {0x0, 0, 1, 2714},
+  {0x0, 0, 1, 2715},
+  {0x0, 3, 4, 2716},
+  {0x0, 3, 4, 2717},
+  {0x0, 8, 9, 2718},
+  {0x21cf, 16, 16, 2719},
+  {0x0, 0, 1, 2719},
+  {0x0, 0, 1, 2720},
+  {0x0, 3, 4, 2721},
+  {0x0, 0, 1, 2722},
+  {0x0, 2, 3, 2723},
+  {0x134, 16, 16, 2724},
+  {0x0, 0, 1, 2724},
+  {0x0, 0, 1, 2725},
+  {0x0, 3, 4, 2726},
+  {0x0, 0, 5, 2727},
+  {0x0, 0, 2, 2732},
+  {0x1f54, 16, 16, 2734},
+  {0x1f52, 16, 16, 2734},
+  {0x0, 1, 2, 2734},
+  {0x1e5e, 16, 16, 2735},
+  {0x0, 8, 9, 2735},
+  {0xf99f, 16, 16, 2736},
+  {0x0, 1, 5, 2736},
+  {0x0, 14, 15, 2740},
+  {0x2f8f2, 16, 16, 2741},
+  {0x205, 16, 16, 2741},
+  {0x11b, 16, 16, 2741},
+  {0x2f88b, 16, 16, 2741},
+  {0x2f88c, 16, 16, 2741},
+  {0x0, 3, 8, 2741},
+  {0x2f81e, 16, 16, 2746},
+  {0x0, 0, 1, 2746},
+  {0x0, 0, 1, 2747},
+  {0x0, 3, 4, 2748},
+  {0x0, 0, 5, 2749},
+  {0x0, 3, 5, 2754},
+  {0x1f01, 16, 16, 2756},
+  {0xfa00, 16, 16, 2756},
+  {0x0, 3, 16, 2756},
+  {0x2f830, 16, 16, 2769},
+  {0x0, 2, 13, 2769},
+  {0x0, 0, 4, 2780},
+  {0x0, 0, 1, 2784},
+  {0x0, 0, 1, 2785},
+  {0x0, 9, 10, 2786},
+  {0x0, 3, 4, 2787},
+  {0x0, 12, 13, 2788},
+  {0x931, 16, 16, 2789},
+  {0x2f833, 16, 16, 2789},
+  {0x0, 0, 1, 2789},
+  {0x0, 0, 1, 2790},
+  {0x0, 3, 4, 2791},
+  {0x0, 0, 1, 2792},
+  {0x0, 8, 9, 2793},
+  {0x1e7a, 16, 16, 2794},
+  {0x0, 14, 15, 2794},
+  {0xf9d0, 16, 16, 2795},
+  {0x0, 9, 14, 2795},
+  {0x2f847, 16, 16, 2800},
+  {0x0, 13, 14, 2800},
+  {0x0, 2, 3, 2801},
+  {0x2f9b1, 16, 16, 2802},
+  {0x0, 4, 13, 2802},
+  {0x0, 7, 8, 2811},
+  {0x0, 0, 1, 2812},
+  {0x0, 0, 1, 2813},
+  {0x0, 11, 12, 2814},
+  {0x0, 3, 6, 2815},
+  {0x0, 14, 15, 2818},
+  {0xb4b, 16, 16, 2819},
+  {0x0, 6, 8, 2819},
+  {0x0, 0, 1, 2821},
+  {0x0, 0, 1, 2822},
+  {0x0, 3, 4, 2823},
+  {0x0, 0, 1, 2824},
+  {0x0, 4, 5, 2825},
+  {0x1e39, 16, 16, 2826},
+  {0x0, 0, 1, 2826},
+  {0x0, 0, 1, 2827},
+  {0x0, 3, 4, 2828},
+  {0x0, 0, 1, 2829},
+  {0x0, 2, 13, 2830},
+  {0x135, 16, 16, 2841},
+  {0x0, 13, 14, 2841},
+  {0x2f9d0, 16, 16, 2842},
+  {0x0, 4, 14, 2842},
+  {0x0, 0, 15, 2852},
+  {0x0, 4, 7, 2867},
+  {0x2f87d, 16, 16, 2870},
+  {0x2f87b, 16, 16, 2870},
+  {0x0, 7, 8, 2870},
+  {0x0, 0, 1, 2871},
+  {0x0, 0, 1, 2872},
+  {0x0, 9, 10, 2873},
+  {0x0, 11, 14, 2874},
+  {0x0, 14, 15, 2877},
+  {0x9cb, 16, 16, 2878},
+  {0x0, 1, 6, 2878},
+  {0x0, 0, 1, 2883},
+  {0x0, 0, 1, 2884},
+  {0x0, 3, 4, 2885},
+  {0x0, 3, 4, 2886},
+  {0x0, 8, 9, 2887},
+  {0x2270, 16, 16, 2888},
+  {0x0, 5, 9, 2888},
+  {0xf959, 16, 16, 2892},
+  {0xfa36, 16, 16, 2892},
+  {0x0, 0, 1, 2892},
+  {0x0, 0, 1, 2893},
+  {0x0, 3, 4, 2894},
+  {0x0, 3, 4, 2895},
+  {0x0, 8, 9, 2896},
+  {0x2271, 16, 16, 2897},
+  {0x0, 9, 10, 2897},
+  {0xfa5e, 16, 16, 2898},
+  {0x0, 0, 1, 2898},
+  {0x0, 0, 1, 2899},
+  {0x0, 3, 4, 2900},
+  {0x0, 0, 1, 2901},
+  {0x0, 1, 2, 2902},
+  {0x453, 16, 16, 2903},
+  {0xf9d3, 16, 16, 2903},
+  {0x0, 12, 14, 2903},
+  {0x0, 0, 1, 2905},
+  {0x0, 0, 1, 2906},
+  {0x0, 3, 4, 2907},
+  {0x0, 0, 1, 2908},
+  {0x0, 2, 3, 2909},
+  {0x1ed8, 16, 16, 2910},
+  {0x0, 2, 16, 2910},
+  {0xf9e7, 16, 16, 2924},
+  {0xf91c, 16, 16, 2924},
+  {0x0, 1, 16, 2924},
+  {0x0, 4, 9, 2939},
+  {0xf901, 16, 16, 2944},
+  {0x2f82f, 16, 16, 2944},
+  {0x0, 15, 16, 2944},
+  {0x2f883, 16, 16, 2945},
+  {0x0, 0, 5, 2945},
+  {0x0, 0, 1, 2950},
+  {0x0, 0, 1, 2951},
+  {0x0, 3, 4, 2952},
+  {0x0, 3, 4, 2953},
+  {0x0, 8, 9, 2954},
+  {0x21ae, 16, 16, 2955},
+  {0x0, 11, 12, 2955},
+  {0x0, 12, 13, 2956},
+  {0x2f8fb, 16, 16, 2957},
+  {0x0, 0, 1, 2957},
+  {0x0, 0, 1, 2958},
+  {0x0, 3, 4, 2959},
+  {0x0, 0, 5, 2960},
+  {0x0, 3, 5, 2965},
+  {0x1f21, 16, 16, 2967},
+  {0x1f0, 16, 16, 2967},
+  {0x1f20, 16, 16, 2967},
+  {0x0, 0, 11, 2967},
+  {0x0, 0, 1, 2978},
+  {0x2f967, 16, 16, 2979},
+  {0x0, 3, 9, 2979},
+  {0x12f, 16, 16, 2985},
+  {0x0, 7, 15, 2985},
+  {0x2f9c7, 16, 16, 2993},
+  {0x1ecb, 16, 16, 2993},
+  {0x0, 2, 12, 2993},
+  {0x0, 0, 1, 3003},
+  {0x0, 3, 4, 3004},
+  {0x0, 0, 1, 3005},
+  {0x0, 9, 10, 3006},
+  {0x0, 9, 11, 3007},
+  {0x30dc, 16, 16, 3009},
+  {0x0, 6, 11, 3009},
+  {0x0, 0, 1, 3014},
+  {0x0, 0, 1, 3015},
+  {0x0, 12, 13, 3016},
+  {0x0, 13, 14, 3017},
+  {0x0, 5, 6, 3018},
+  {0xccb, 16, 16, 3019},
+  {0x0, 4, 9, 3019},
+  {0x2f9e7, 16, 16, 3024},
+  {0x0, 3, 8, 3024},
+  {0x1e32, 16, 16, 3029},
+  {0x0, 0, 1, 3029},
+  {0x0, 0, 1, 3030},
+  {0x0, 3, 4, 3031},
+  {0x0, 0, 5, 3032},
+  {0x0, 2, 3, 3037},
+  {0x1f36, 16, 16, 3038},
+  {0x0, 3, 14, 3038},
+  {0x0, 0, 1, 3049},
+  {0x0, 0, 1, 3050},
+  {0x0, 3, 4, 3051},
+  {0x0, 0, 1, 3052},
+  {0x0, 4, 12, 3053},
+  {0x45e, 16, 16, 3061},
+  {0x136, 16, 16, 3061},
+  {0x0, 6, 8, 3061},
+  {0x0, 0, 1, 3063},
+  {0x0, 0, 1, 3064},
+  {0x0, 11, 12, 3065},
+  {0x0, 11, 14, 3066},
+  {0x0, 7, 8, 3069},
+  {0xbcc, 16, 16, 3070},
+  {0x0, 3, 4, 3070},
+  {0xf981, 16, 16, 3071},
+  {0x0, 0, 1, 3071},
+  {0x0, 0, 1, 3072},
+  {0x0, 3, 4, 3073},
+  {0x0, 0, 4, 3074},
+  {0x0, 0, 16, 3078},
+  {0x1ec8, 16, 16, 3094},
+  {0x0, 3, 4, 3094},
+  {0x343, 16, 16, 3095},
+  {0x12c, 16, 16, 3095},
+  {0x0, 3, 16, 3095},
+  {0x2f870, 16, 16, 3108},
+  {0xf9b1, 16, 16, 3108},
+  {0x0, 0, 15, 3108},
+  {0x2f97f, 16, 16, 3123},
+  {0x2f8cc, 16, 16, 3123},
+  {0x0, 0, 1, 3123},
+  {0x0, 0, 1, 3124},
+  {0x0, 3, 4, 3125},
+  {0x0, 0, 1, 3126},
+  {0x0, 4, 5, 3127},
+  {0x1ed, 16, 16, 3128},
+  {0x30dd, 16, 16, 3128},
+  {0x0, 0, 7, 3128},
+  {0x0, 11, 12, 3135},
+  {0x2f984, 16, 16, 3136},
+  {0x0, 1, 12, 3136},
+  {0x0, 13, 14, 3147},
+  {0x0, 4, 5, 3148},
+  {0x2f8a4, 16, 16, 3149},
+  {0x2f9c6, 16, 16, 3149},
+  {0x2f872, 16, 16, 3149},
+  {0x0, 2, 16, 3149},
+  {0x0, 12, 13, 3163},
+  {0xf9c3, 16, 16, 3164},
+  {0xf945, 16, 16, 3164},
+  {0x0, 5, 6, 3164},
+  {0xf90f, 16, 16, 3165},
+  {0x0, 1, 16, 3165},
+  {0x0, 13, 14, 3180},
+  {0x2f884, 16, 16, 3181},
+  {0x0, 0, 1, 3181},
+  {0x0, 0, 1, 3182},
+  {0x0, 3, 4, 3183},
+  {0x0, 0, 1, 3184},
+  {0x0, 8, 9, 3185},
+  {0x4f9, 16, 16, 3186},
+  {0x0, 5, 6, 3186},
+  {0x2f921, 16, 16, 3187},
+  {0x0, 8, 10, 3187},
+  {0xfa4d, 16, 16, 3189},
+  {0xfa4e, 16, 16, 3189},
+  {0x0, 1, 16, 3189},
+  {0x0, 11, 12, 3204},
+  {0x2fa15, 16, 16, 3205},
+  {0x0, 7, 16, 3205},
+  {0xf988, 16, 16, 3214},
+  {0x0, 11, 12, 3214},
+  {0x2f863, 16, 16, 3215},
+  {0x0, 0, 5, 3215},
+  {0x0, 7, 8, 3220},
+  {0xf950, 16, 16, 3221},
+  {0x0, 0, 16, 3221},
+  {0x0, 9, 16, 3237},
+  {0xf95b, 16, 16, 3244},
+  {0x0, 0, 1, 3244},
+  {0x0, 0, 1, 3245},
+  {0x0, 3, 4, 3246},
+  {0x0, 0, 1, 3247},
+  {0x0, 7, 9, 3248},
+  {0x1e8a, 16, 16, 3250},
+  {0x0, 0, 1, 3250},
+  {0x0, 0, 1, 3251},
+  {0x0, 3, 4, 3252},
+  {0x0, 0, 5, 3253},
+  {0x0, 0, 2, 3258},
+  {0x3b0, 16, 16, 3260},
+  {0x1fe2, 16, 16, 3260},
+  {0x0, 1, 15, 3260},
+  {0x0, 2, 3, 3274},
+  {0x2f8e8, 16, 16, 3275},
+  {0xf9f3, 16, 16, 3275},
+  {0x1e8c, 16, 16, 3275},
+  {0x0, 0, 1, 3275},
+  {0x0, 3, 4, 3276},
+  {0x0, 0, 1, 3277},
+  {0x0, 9, 10, 3278},
+  {0x0, 9, 10, 3279},
+  {0x30bc, 16, 16, 3280},
+  {0x0, 0, 1, 3280},
+  {0x0, 0, 1, 3281},
+  {0x0, 3, 4, 3282},
+  {0x0, 0, 1, 3283},
+  {0x0, 4, 5, 3284},
+  {0x1e38, 16, 16, 3285},
+  {0x0, 9, 10, 3285},
+  {0xf966, 16, 16, 3286},
+  {0x0, 2, 3, 3286},
+  {0x0, 14, 15, 3287},
+  {0x2f9e5, 16, 16, 3288},
+  {0x0, 1, 2, 3288},
+  {0x206, 16, 16, 3289},
+  {0x0, 5, 16, 3289},
+  {0x1fcb, 16, 16, 3300},
+  {0x0, 3, 4, 3300},
+  {0x1e42, 16, 16, 3301},
+  {0x0, 4, 16, 3301},
+  {0x0, 0, 1, 3313},
+  {0x2fa0b, 16, 16, 3314},
+  {0x0, 13, 14, 3314},
+  {0x2f89d, 16, 16, 3315},
+  {0x0, 1, 15, 3315},
+  {0xfa44, 16, 16, 3329},
+  {0x0, 8, 13, 3329},
+  {0xfa3a, 16, 16, 3334},
+  {0x0, 1, 15, 3334},
+  {0x0, 2, 13, 3348},
+  {0xf960, 16, 16, 3359},
+  {0x0, 1, 2, 3359},
+  {0x0, 13, 14, 3360},
+  {0x2f94d, 16, 16, 3361},
+  {0x0, 13, 14, 3361},
+  {0xf923, 16, 16, 3362},
+  {0x0, 4, 5, 3362},
+  {0xf91d, 16, 16, 3363},
+  {0x0, 12, 13, 3363},
+  {0x0, 14, 15, 3364},
+  {0x2fa10, 16, 16, 3365},
+  {0x0, 0, 1, 3365},
+  {0x0, 0, 1, 3366},
+  {0x0, 3, 4, 3367},
+  {0x0, 0, 5, 3368},
+  {0x0, 0, 2, 3373},
+  {0x1f33, 16, 16, 3375},
+  {0x0, 0, 1, 3375},
+  {0x0, 0, 1, 3376},
+  {0x0, 3, 4, 3377},
+  {0x0, 0, 1, 3378},
+  {0x0, 7, 8, 3379},
+  {0x1e1e, 16, 16, 3380},
+  {0x1f35, 16, 16, 3380},
+  {0x0, 15, 16, 3380},
+  {0xfa41, 16, 16, 3381},
+  {0xf9ac, 16, 16, 3381},
+  {0x2f858, 16, 16, 3381},
+  {0x0, 0, 1, 3381},
+  {0x0, 0, 1, 3382},
+  {0x0, 3, 4, 3383},
+  {0x0, 4, 5, 3384},
+  {0x0, 5, 6, 3385},
+  {0x1f82, 16, 16, 3386},
+  {0x0, 11, 12, 3386},
+  {0xf9d8, 16, 16, 3387},
+  {0x0, 0, 15, 3387},
+  {0x0, 0, 1, 3402},
+  {0x0, 0, 1, 3403},
+  {0x0, 3, 4, 3404},
+  {0x0, 0, 1, 3405},
+  {0x0, 0, 9, 3406},
+  {0x4d6, 16, 16, 3415},
+  {0x0, 5, 6, 3415},
+  {0xf983, 16, 16, 3416},
+  {0x400, 16, 16, 3416},
+  {0x0, 0, 1, 3416},
+  {0x0, 0, 1, 3417},
+  {0x0, 3, 4, 3418},
+  {0x0, 0, 5, 3419},
+  {0x0, 0, 2, 3424},
+  {0x1f0d, 16, 16, 3426},
+  {0x1f0b, 16, 16, 3426},
+  {0x401, 16, 16, 3426},
+  {0x0, 10, 14, 3426},
+  {0x2f8c5, 16, 16, 3430},
+  {0xf991, 16, 16, 3430},
+  {0x0, 1, 2, 3430},
+  {0x207, 16, 16, 3431},
+  {0x0, 10, 12, 3431},
+  {0x0, 0, 1, 3433},
+  {0x0, 0, 1, 3434},
+  {0x0, 3, 4, 3435},
+  {0x0, 0, 1, 3436},
+  {0x0, 7, 8, 3437},
+  {0x1e64, 16, 16, 3438},
+  {0x0, 5, 6, 3438},
+  {0x2f9a6, 16, 16, 3439},
+  {0x0, 4, 8, 3439},
+  {0x387, 16, 16, 3443},
+  {0x1ffd, 16, 16, 3443},
+  {0x0, 9, 11, 3443},
+  {0xf928, 16, 16, 3445},
+  {0x0, 0, 1, 3445},
+  {0x0, 0, 1, 3446},
+  {0x0, 3, 4, 3447},
+  {0x0, 0, 3, 3448},
+  {0x0, 3, 4, 3451},
+  {0x1ee2, 16, 16, 3452},
+  {0x0, 4, 16, 3452},
+  {0x0, 4, 14, 3464},
+  {0xf9d1, 16, 16, 3474},
+  {0x0, 1, 14, 3474},
+  {0x0, 1, 12, 3487},
+  {0x2f9e6, 16, 16, 3498},
+  {0x0, 13, 14, 3498},
+  {0x2fa0c, 16, 16, 3499},
+  {0x0, 0, 1, 3499},
+  {0x0, 0, 1, 3500},
+  {0x0, 3, 4, 3501},
+  {0x0, 0, 1, 3502},
+  {0x0, 4, 5, 3503},
+  {0x230, 16, 16, 3504},
+  {0x0, 0, 1, 3504},
+  {0x0, 0, 1, 3505},
+  {0x0, 3, 4, 3506},
+  {0x0, 4, 5, 3507},
+  {0x0, 5, 6, 3508},
+  {0x1faf, 16, 16, 3509},
+  {0x0, 14, 15, 3509},
+  {0xf9a6, 16, 16, 3510},
+  {0x0, 13, 14, 3510},
+  {0x2f87a, 16, 16, 3511},
+  {0x0, 0, 7, 3511},
+  {0x3ac, 16, 16, 3518},
+  {0x1f70, 16, 16, 3518},
+  {0x0, 7, 8, 3518},
+  {0x0, 0, 1, 3519},
+  {0x0, 0, 1, 3520},
+  {0x0, 6, 7, 3521},
+  {0x0, 5, 6, 3522},
+  {0x0, 3, 6, 3523},
+  {0x623, 16, 16, 3526},
+  {0x625, 16, 16, 3526},
+  {0x1fb1, 16, 16, 3526},
+  {0x1fb0, 16, 16, 3526},
+  {0xf9a2, 16, 16, 3526},
+  {0x0, 10, 11, 3526},
+  {0xf9d6, 16, 16, 3527},
+  {0x0, 3, 4, 3527},
+  {0x2f844, 16, 16, 3528},
+  {0x0, 1, 2, 3528},
+  {0x1e0f, 16, 16, 3529},
+  {0x0, 14, 15, 3529},
+  {0xf9c0, 16, 16, 3530},
+  {0x0, 6, 7, 3530},
+  {0xf9dc, 16, 16, 3531},
+  {0x2f810, 16, 16, 3531},
+  {0x2f814, 16, 16, 3531},
+  {0xf978, 16, 16, 3531},
+  {0x2f9e4, 16, 16, 3531},
+  {0x0, 0, 16, 3531},
+  {0x0, 13, 14, 3547},
+  {0xf9ed, 16, 16, 3548},
+  {0x0, 0, 1, 3548},
+  {0x0, 3, 4, 3549},
+  {0x0, 0, 1, 3550},
+  {0x0, 9, 10, 3551},
+  {0x0, 9, 11, 3552},
+  {0x3071, 16, 16, 3554},
+  {0x0, 2, 16, 3554},
+  {0x0, 1, 12, 3568},
+  {0x2f9af, 16, 16, 3579},
+  {0x0, 0, 1, 3579},
+  {0x0, 0, 1, 3580},
+  {0x0, 3, 4, 3581},
+  {0x0, 0, 4, 3582},
+  {0x0, 3, 14, 3586},
+  {0x1e4b, 16, 16, 3597},
+  {0x0, 0, 1, 3597},
+  {0x0, 0, 1, 3598},
+  {0x0, 3, 4, 3599},
+  {0x0, 4, 5, 3600},
+  {0x0, 5, 6, 3601},
+  {0x1f9a, 16, 16, 3602},
+  {0x0, 5, 7, 3602},
+  {0x2f829, 16, 16, 3604},
+  {0x2f82a, 16, 16, 3604},
+  {0x0, 3, 16, 3604},
+  {0x0, 14, 15, 3617},
+  {0xf999, 16, 16, 3618},
+  {0x0, 7, 15, 3618},
+  {0xf9bc, 16, 16, 3626},
+  {0x0, 0, 1, 3626},
+  {0x0, 0, 1, 3627},
+  {0x0, 3, 4, 3628},
+  {0x0, 3, 4, 3629},
+  {0x0, 8, 9, 3630},
+  {0x21cd, 16, 16, 3631},
+  {0x0, 0, 1, 3631},
+  {0x0, 0, 1, 3632},
+  {0x0, 3, 4, 3633},
+  {0x0, 3, 4, 3634},
+  {0x0, 8, 9, 3635},
+  {0x2262, 16, 16, 3636},
+  {0x0, 0, 2, 3636},
+  {0x3ae, 16, 16, 3638},
+  {0x1f74, 16, 16, 3638},
+  {0x0, 0, 1, 3638},
+  {0x0, 0, 1, 3639},
+  {0x0, 3, 4, 3640},
+  {0x0, 0, 4, 3641},
+  {0x0, 1, 2, 3645},
+  {0x1e96, 16, 16, 3646},
+  {0x0, 0, 1, 3646},
+  {0x0, 3, 4, 3647},
+  {0x0, 0, 1, 3648},
+  {0x0, 9, 10, 3649},
+  {0x0, 9, 10, 3650},
+  {0x30b8, 16, 16, 3651},
+  {0x0, 2, 7, 3651},
+  {0xf97d, 16, 16, 3656},
+  {0xf941, 16, 16, 3656},
+  {0x1e47, 16, 16, 3656},
+  {0x146, 16, 16, 3656},
+  {0x0, 0, 1, 3656},
+  {0x1e2d, 16, 16, 3657},
+  {0x2f9b2, 16, 16, 3657},
+  {0x0, 0, 1, 3657},
+  {0xf9fa, 16, 16, 3658},
+  {0x3070, 16, 16, 3658},
+  {0x0, 8, 9, 3658},
+  {0xf90c, 16, 16, 3659},
+  {0x0, 0, 1, 3659},
+  {0x0, 0, 1, 3660},
+  {0x0, 3, 4, 3661},
+  {0x0, 0, 1, 3662},
+  {0x0, 0, 10, 3663},
+  {0x1ea6, 16, 16, 3673},
+  {0x1ea4, 16, 16, 3673},
+  {0x1eaa, 16, 16, 3673},
+  {0x0, 14, 15, 3673},
+  {0xf92c, 16, 16, 3674},
+  {0x1ea8, 16, 16, 3674},
+  {0x0, 0, 1, 3674},
+  {0x0, 3, 4, 3675},
+  {0x0, 0, 1, 3676},
+  {0x0, 9, 10, 3677},
+  {0x0, 9, 10, 3678},
+  {0x30c2, 16, 16, 3679},
+  {0x0, 0, 9, 3679},
+  {0x340, 16, 16, 3688},
+  {0x341, 16, 16, 3688},
+  {0x0, 0, 15, 3688},
+  {0x0, 6, 7, 3703},
+  {0x2f94c, 16, 16, 3704},
+  {0x0, 3, 4, 3704},
+  {0x2f8e9, 16, 16, 3705},
+  {0x0, 6, 7, 3705},
+  {0xf9fe, 16, 16, 3706},
+  {0x0, 8, 9, 3706},
+  {0x0, 0, 1, 3707},
+  {0x2f965, 16, 16, 3708},
+  {0x0, 12, 13, 3708},
+  {0x0, 0, 1, 3709},
+  {0x0, 0, 1, 3710},
+  {0x0, 3, 4, 3711},
+  {0x0, 3, 4, 3712},
+  {0x0, 8, 9, 3713},
+  {0x2241, 16, 16, 3714},
+  {0x1f75, 0, 1, 3714},
+  {0x0, 0, 1, 3715},
+  {0x0, 3, 4, 3716},
+  {0x0, 4, 5, 3717},
+  {0x0, 5, 6, 3718},
+  {0x1fc4, 16, 16, 3719},
+  {0x0, 8, 9, 3719},
+  {0x0, 1, 2, 3720},
+  {0x2f876, 16, 16, 3721},
+  {0x0, 0, 15, 3721},
+  {0xfa19, 16, 16, 3736},
+  {0x0, 15, 16, 3736},
+  {0x0, 0, 1, 3737},
+  {0x0, 3, 4, 3738},
+  {0x0, 0, 1, 3739},
+  {0x0, 9, 10, 3740},
+  {0x0, 9, 10, 3741},
+  {0x30f7, 16, 16, 3742},
+  {0x0, 1, 2, 3742},
+  {0xf9e8, 16, 16, 3743},
+  {0x0, 1, 16, 3743},
+  {0x154, 16, 16, 3758},
+  {0x0, 7, 8, 3758},
+  {0x0, 12, 13, 3759},
+  {0x2f95c, 16, 16, 3760},
+  {0x0, 7, 8, 3760},
+  {0xf933, 16, 16, 3761},
+  {0x0, 0, 16, 3761},
+  {0x0, 3, 11, 3777},
+  {0x2f8df, 16, 16, 3785},
+  {0xfa50, 16, 16, 3785},
+  {0xfa4f, 16, 16, 3785},
+  {0x0, 8, 12, 3785},
+  {0x2f920, 16, 16, 3789},
+  {0x0, 3, 4, 3789},
+  {0x1e88, 16, 16, 3790},
+  {0x0, 0, 1, 3790},
+  {0x0, 3, 4, 3791},
+  {0x0, 0, 1, 3792},
+  {0x0, 9, 10, 3793},
+  {0x0, 9, 11, 3794},
+  {0x3077, 16, 16, 3796},
+  {0x0, 10, 11, 3796},
+  {0x2f917, 16, 16, 3797},
+  {0x0, 14, 16, 3797},
+  {0x0, 12, 13, 3799},
+  {0x2f868, 16, 16, 3800},
+  {0x0, 1, 7, 3800},
+  {0x0, 2, 3, 3806},
+  {0x2fa0a, 16, 16, 3807},
+  {0x0, 0, 1, 3807},
+  {0x0, 0, 1, 3808},
+  {0x0, 3, 4, 3809},
+  {0x0, 4, 5, 3810},
+  {0x0, 5, 6, 3811},
+  {0x1f86, 16, 16, 3812},
+  {0x0, 1, 6, 3812},
+  {0xfa59, 16, 16, 3817},
+  {0x2f970, 16, 16, 3817},
+  {0x0, 9, 10, 3817},
+  {0x2f887, 16, 16, 3818},
+  {0x0, 0, 9, 3818},
+  {0x0, 8, 9, 3827},
+  {0xf9fc, 16, 16, 3828},
+  {0x0, 7, 8, 3828},
+  {0xf9f4, 16, 16, 3829},
+  {0x0, 8, 10, 3829},
+  {0x0, 0, 1, 3831},
+  {0x0, 0, 1, 3832},
+  {0x0, 3, 4, 3833},
+  {0x0, 0, 1, 3834},
+  {0x0, 8, 9, 3835},
+  {0x4da, 16, 16, 3836},
+  {0x0, 1, 2, 3836},
+  {0xf9b9, 16, 16, 3837},
+  {0x0, 3, 13, 3837},
+  {0x0, 14, 15, 3847},
+  {0x2f9cd, 16, 16, 3848},
+  {0x0, 6, 7, 3848},
+  {0x2f866, 16, 16, 3849},
+  {0x0, 8, 10, 3849},
+  {0x0, 0, 1, 3851},
+  {0x0, 0, 1, 3852},
+  {0x0, 3, 4, 3853},
+  {0x0, 0, 1, 3854},
+  {0x0, 2, 3, 3855},
+  {0x1ec7, 16, 16, 3856},
+  {0x0, 14, 15, 3856},
+  {0x2f867, 16, 16, 3857},
+  {0x0, 3, 14, 3857},
+  {0x118, 16, 16, 3868},
+  {0x0, 0, 1, 3868},
+  {0x0, 0, 1, 3869},
+  {0x0, 3, 4, 3870},
+  {0x0, 0, 5, 3871},
+  {0x0, 0, 2, 3876},
+  {0x1f2d, 16, 16, 3878},
+  {0x228, 16, 16, 3878},
+  {0x0, 4, 15, 3878},
+  {0x0, 7, 8, 3889},
+  {0x2f8fe, 16, 16, 3890},
+  {0x1eb8, 16, 16, 3890},
+  {0x0, 2, 13, 3890},
+  {0x0, 0, 1, 3901},
+  {0xf9f8, 16, 16, 3902},
+  {0x0, 14, 15, 3902},
+  {0xf989, 16, 16, 3903},
+  {0x0, 2, 8, 3903},
+  {0x2f8f3, 16, 16, 3909},
+  {0x0, 6, 7, 3909},
+  {0x2f873, 16, 16, 3910},
+  {0x0, 0, 16, 3910},
+  {0x0, 1, 2, 3926},
+  {0x2f8be, 16, 16, 3927},
+  {0x0, 12, 15, 3927},
+  {0xfa18, 16, 16, 3930},
+  {0x0, 8, 9, 3930},
+  {0xf969, 16, 16, 3931},
+  {0x0, 5, 13, 3931},
+  {0x0, 3, 13, 3939},
+  {0x2f98a, 16, 16, 3949},
+  {0x0, 9, 10, 3949},
+  {0xf9cd, 16, 16, 3950},
+  {0x1e18, 16, 16, 3950},
+  {0x0, 0, 1, 3950},
+  {0x0, 0, 1, 3951},
+  {0x0, 3, 4, 3952},
+  {0x0, 0, 1, 3953},
+  {0x0, 4, 5, 3954},
+  {0x1e5c, 16, 16, 3955},
+  {0xf98c, 16, 16, 3955},
+  {0x0, 12, 16, 3955},
+  {0x0, 13, 14, 3959},
+  {0x2fa0e, 16, 16, 3960},
+  {0x0, 9, 14, 3960},
+  {0x0, 15, 16, 3965},
+  {0x2f81f, 16, 16, 3966},
+  {0x0, 2, 13, 3966},
+  {0x0, 6, 7, 3977},
+  {0x2f952, 16, 16, 3978},
+  {0x0, 0, 1, 3978},
+  {0x0, 0, 1, 3979},
+  {0x0, 3, 4, 3980},
+  {0x0, 0, 3, 3981},
+  {0x0, 1, 13, 3984},
+  {0x160, 16, 16, 3996},
+  {0x0, 0, 1, 3996},
+  {0x0, 3, 4, 3997},
+  {0x0, 0, 1, 3998},
+  {0x0, 9, 10, 3999},
+  {0x0, 9, 10, 4000},
+  {0x30ac, 16, 16, 4001},
+  {0x0, 9, 10, 4001},
+  {0xf9d5, 16, 16, 4002},
+  {0x0, 0, 1, 4002},
+  {0x0, 0, 1, 4003},
+  {0x0, 3, 4, 4004},
+  {0x0, 0, 5, 4005},
+  {0x0, 0, 2, 4010},
+  {0x3ce, 16, 16, 4012},
+  {0x0, 11, 12, 4012},
+  {0x2f8f8, 16, 16, 4013},
+  {0x0, 0, 1, 4013},
+  {0x0, 0, 1, 4014},
+  {0x0, 3, 4, 4015},
+  {0x0, 0, 1, 4016},
+  {0x0, 0, 9, 4017},
+  {0x451, 16, 16, 4026},
+  {0x450, 16, 16, 4026},
+  {0x0, 3, 13, 4026},
+  {0x0, 3, 4, 4036},
+  {0x2fa03, 16, 16, 4037},
+  {0x4d7, 16, 16, 4037},
+  {0xf9c9, 16, 16, 4037},
+  {0x1e60, 16, 16, 4037},
+  {0x15a, 16, 16, 4037},
+  {0x15c, 16, 16, 4037},
+  {0xf91e, 16, 16, 4037},
+  {0x0, 0, 1, 4037},
+  {0x0, 0, 1, 4038},
+  {0x0, 3, 4, 4039},
+  {0x0, 0, 1, 4040},
+  {0x0, 0, 10, 4041},
+  {0x1eab, 16, 16, 4051},
+  {0x1ea7, 16, 16, 4051},
+  {0x1ea5, 16, 16, 4051},
+  {0x1ea9, 16, 16, 4051},
+  {0x0, 2, 14, 4051},
+  {0x0, 10, 11, 4063},
+  {0xfa16, 16, 16, 4064},
+  {0x0, 11, 12, 4064},
+  {0xf9a4, 16, 16, 4065},
+  {0x0, 0, 1, 4065},
+  {0x0, 0, 1, 4066},
+  {0x0, 3, 4, 4067},
+  {0x0, 3, 4, 4068},
+  {0x0, 8, 9, 4069},
+  {0x226d, 16, 16, 4070},
+  {0x0, 0, 1, 4070},
+  {0x0, 0, 1, 4071},
+  {0x0, 3, 4, 4072},
+  {0x0, 4, 5, 4073},
+  {0x0, 5, 6, 4074},
+  {0x1f9f, 16, 16, 4075},
+  {0x0, 0, 1, 4075},
+  {0x0, 0, 1, 4076},
+  {0x0, 3, 4, 4077},
+  {0x0, 4, 5, 4078},
+  {0x0, 5, 6, 4079},
+  {0x1fad, 16, 16, 4080},
+  {0x0, 0, 1, 4080},
+  {0x0, 0, 1, 4081},
+  {0x0, 3, 4, 4082},
+  {0x0, 0, 3, 4083},
+  {0x0, 3, 4, 4086},
+  {0x1ee3, 16, 16, 4087},
+  {0x0, 13, 14, 4087},
+  {0x2f9ae, 16, 16, 4088},
+  {0x0, 3, 15, 4088},
+  {0x1e2b, 16, 16, 4100},
+  {0x0, 12, 13, 4100},
+  {0x2f9ea, 16, 16, 4101},
+  {0x0, 12, 13, 4101},
+  {0x0, 10, 11, 4102},
+  {0x2f9ab, 16, 16, 4103},
+  {0x0, 0, 1, 4103},
+  {0x0, 0, 1, 4104},
+  {0x0, 3, 4, 4105},
+  {0x0, 0, 5, 4106},
+  {0x0, 0, 7, 4111},
+  {0x1fba, 16, 16, 4118},
+  {0x386, 16, 16, 4118},
+  {0x1fb8, 16, 16, 4118},
+  {0x0, 7, 8, 4118},
+  {0x2f811, 16, 16, 4119},
+  {0x1fb9, 16, 16, 4119},
+  {0x0, 1, 14, 4119},
+  {0x0, 14, 15, 4132},
+  {0x2f909, 16, 16, 4133},
+  {0x0, 0, 13, 4133},
+  {0xf936, 16, 16, 4146},
+  {0x0, 6, 7, 4146},
+  {0x0, 0, 1, 4147},
+  {0x0, 0, 1, 4148},
+  {0x0, 3, 4, 4149},
+  {0x0, 4, 5, 4150},
+  {0x0, 5, 6, 4151},
+  {0x1fc7, 16, 16, 4152},
+  {0x0, 0, 11, 4152},
+  {0x0, 0, 1, 4163},
+  {0x0, 0, 1, 4164},
+  {0x0, 3, 4, 4165},
+  {0x0, 0, 1, 4166},
+  {0x0, 7, 9, 4167},
+  {0x1e8b, 16, 16, 4169},
+  {0x0, 1, 8, 4169},
+  {0x1e3f, 16, 16, 4176},
+  {0x1e41, 16, 16, 4176},
+  {0x0, 0, 16, 4176},
+  {0x0, 4, 5, 4192},
+  {0xf93f, 16, 16, 4193},
+  {0x0, 7, 8, 4193},
+  {0x2f964, 16, 16, 4194},
+  {0x0, 6, 7, 4194},
+  {0x2f9be, 16, 16, 4195},
+  {0x1e8d, 16, 16, 4195},
+  {0x0, 0, 1, 4195},
+  {0x0, 0, 1, 4196},
+  {0x0, 3, 4, 4197},
+  {0x0, 0, 1, 4198},
+  {0x0, 0, 2, 4199},
+  {0x1e14, 16, 16, 4201},
+  {0x0, 7, 8, 4201},
+  {0xfa31, 16, 16, 4202},
+  {0x0, 0, 1, 4202},
+  {0x0, 0, 1, 4203},
+  {0x0, 3, 4, 4204},
+  {0x0, 0, 1, 4205},
+  {0x0, 1, 2, 4206},
+  {0x1e2f, 16, 16, 4207},
+  {0x0, 7, 8, 4207},
+  {0xf963, 16, 16, 4208},
+  {0x2f9b3, 16, 16, 4208},
+  {0x0, 0, 1, 4208},
+  {0x0, 0, 1, 4209},
+  {0x0, 3, 4, 4210},
+  {0x0, 0, 5, 4211},
+  {0x0, 2, 3, 4216},
+  {0x1f3e, 16, 16, 4217},
+  {0x0, 0, 1, 4217},
+  {0x0, 0, 1, 4218},
+  {0x0, 3, 4, 4219},
+  {0x0, 0, 1, 4220},
+  {0x0, 1, 2, 4221},
+  {0x1e2e, 16, 16, 4222},
+  {0x1e29, 16, 16, 4222},
+  {0x0, 0, 1, 4222},
+  {0x0, 0, 1, 4223},
+  {0x0, 3, 4, 4224},
+  {0x0, 0, 4, 4225},
+  {0x0, 1, 2, 4229},
+  {0x1e06, 16, 16, 4230},
+  {0x1e25, 16, 16, 4230},
+  {0xec, 16, 16, 4230},
+  {0xed, 16, 16, 4230},
+  {0xee, 16, 16, 4230},
+  {0x129, 16, 16, 4230},
+  {0x12b, 16, 16, 4230},
+  {0x12d, 16, 16, 4230},
+  {0xef, 16, 16, 4230},
+  {0x1ec9, 16, 16, 4230},
+  {0x0, 6, 16, 4230},
+  {0x2f83b, 16, 16, 4240},
+  {0x0, 1, 2, 4240},
+  {0xf909, 16, 16, 4241},
+  {0x2f969, 16, 16, 4241},
+  {0x0, 8, 11, 4241},
+  {0x2f9c9, 16, 16, 4244},
+  {0x0, 1, 13, 4244},
+  {0x1e30, 16, 16, 4256},
+  {0x1a1, 16, 16, 4256},
+  {0x0, 3, 12, 4256},
+  {0x0, 0, 1, 4265},
+  {0x0, 0, 1, 4266},
+  {0x0, 3, 4, 4267},
+  {0x0, 3, 4, 4268},
+  {0x0, 8, 9, 4269},
+  {0x2209, 16, 16, 4270},
+  {0x0, 13, 14, 4270},
+  {0xf918, 16, 16, 4271},
+  {0xf97b, 16, 16, 4271},
+  {0x0, 1, 13, 4271},
+  {0x2f9a9, 16, 16, 4283},
+  {0x2f9a8, 16, 16, 4283},
+  {0x0, 8, 9, 4283},
+  {0x2f86e, 16, 16, 4284},
+  {0x0, 4, 5, 4284},
+  {0x2f9e2, 16, 16, 4285},
+  {0xf9de, 16, 16, 4285},
+  {0x1e8, 16, 16, 4285},
+  {0x0, 3, 4, 4285},
+  {0x2f99c, 16, 16, 4286},
+  {0x0, 6, 7, 4286},
+  {0x2f94b, 16, 16, 4287},
+  {0x209, 16, 16, 4287},
+  {0x0, 2, 3, 4287},
+  {0xfa4a, 16, 16, 4288},
+  {0xf9c2, 16, 16, 4288},
+  {0x0, 0, 1, 4288},
+  {0x0, 0, 1, 4289},
+  {0x0, 3, 4, 4290},
+  {0x0, 0, 1, 4291},
+  {0x0, 8, 9, 4292},
+  {0x4db, 16, 16, 4293},
+  {0x0, 5, 6, 4293},
+  {0xfa1a, 16, 16, 4294},
+  {0x0, 4, 15, 4294},
+  {0x2f8a9, 16, 16, 4305},
+  {0x0, 3, 14, 4305},
+  {0x0, 0, 1, 4316},
+  {0x0, 0, 1, 4317},
+  {0x0, 3, 4, 4318},
+  {0x0, 0, 1, 4319},
+  {0x0, 4, 12, 4320},
+  {0x4f0, 16, 16, 4328},
+  {0x0, 5, 10, 4328},
+  {0xf993, 16, 16, 4333},
+  {0x2f8a8, 16, 16, 4333},
+  {0x2f91c, 16, 16, 4333},
+  {0x40e, 16, 16, 4333},
+  {0x4ee, 16, 16, 4333},
+  {0x0, 5, 6, 4333},
+  {0x2f986, 16, 16, 4334},
+  {0x0, 11, 12, 4334},
+  {0xf922, 16, 16, 4335},
+  {0x0, 5, 6, 4335},
+  {0x1fcc, 16, 16, 4336},
+  {0x0, 0, 1, 4336},
+  {0x0, 3, 4, 4337},
+  {0x0, 0, 1, 4338},
+  {0x0, 9, 10, 4339},
+  {0x0, 9, 10, 4340},
+  {0x3056, 16, 16, 4341},
+  {0x0, 7, 16, 4341},
+  {0xf9da, 16, 16, 4350},
+  {0x0, 7, 8, 4350},
+  {0x2f96e, 16, 16, 4351},
+  {0xf9d9, 16, 16, 4351},
+  {0x4f2, 16, 16, 4351},
+  {0x2f8a6, 16, 16, 4351},
+  {0x0, 8, 9, 4351},
+  {0x2f869, 16, 16, 4352},
+  {0x0, 8, 9, 4352},
+  {0xf9ef, 16, 16, 4353},
+  {0x0, 5, 6, 4353},
+  {0x2f8e0, 16, 16, 4354},
+  {0x0, 0, 9, 4354},
+  {0x0, 11, 12, 4363},
+  {0x2f94a, 16, 16, 4364},
+  {0x0, 0, 10, 4364},
+  {0x0, 13, 14, 4374},
+  {0xf9c4, 16, 16, 4375},
+  {0x2f8e5, 16, 16, 4375},
+  {0x0, 0, 1, 4375},
+  {0x1e1a, 16, 16, 4376},
+  {0x0, 10, 11, 4376},
+  {0x0, 11, 12, 4377},
+  {0x2f91f, 16, 16, 4378},
+  {0x0, 0, 1, 4378},
+  {0x0, 0, 1, 4379},
+  {0x0, 3, 4, 4380},
+  {0x0, 0, 3, 4381},
+  {0x0, 0, 16, 4384},
+  {0x200, 16, 16, 4400},
+  {0x1cd, 16, 16, 4400},
+  {0xc5, 16, 16, 4400},
+  {0x0, 13, 14, 4400},
+  {0x2f8d6, 16, 16, 4401},
+  {0x0, 5, 6, 4401},
+  {0xf976, 16, 16, 4402},
+  {0x0, 6, 12, 4402},
+  {0xf9b5, 16, 16, 4408},
+  {0x0, 0, 1, 4408},
+  {0x0, 0, 1, 4409},
+  {0x0, 3, 4, 4410},
+  {0x0, 0, 4, 4411},
+  {0x0, 3, 14, 4415},
+  {0x21a, 16, 16, 4426},
+  {0x162, 16, 16, 4426},
+  {0x1e6c, 16, 16, 4426},
+  {0x0, 0, 2, 4426},
+  {0x1f05, 16, 16, 4428},
+  {0x1f03, 16, 16, 4428},
+  {0x0, 1, 2, 4428},
+  {0x2f8ef, 16, 16, 4429},
+  {0x0, 7, 8, 4429},
+  {0x2f9ce, 16, 16, 4430},
+  {0xf92d, 16, 16, 4430},
+  {0x0, 10, 15, 4430},
+  {0x0, 8, 9, 4435},
+  {0x2f860, 16, 16, 4436},
+  {0x1e70, 16, 16, 4436},
+  {0x0, 4, 5, 4436},
+  {0xfa2d, 16, 16, 4437},
+  {0x0, 12, 13, 4437},
+  {0x2f8c9, 16, 16, 4438},
+  {0x102, 16, 16, 4438},
+  {0x226, 16, 16, 4438},
+  {0x100, 16, 16, 4438},
+  {0xc2, 16, 16, 4438},
+  {0xc3, 16, 16, 4438},
+  {0xc0, 16, 16, 4438},
+  {0xc1, 16, 16, 4438},
+  {0x0, 2, 3, 4438},
+  {0x2fa06, 16, 16, 4439},
+  {0x0, 2, 3, 4439},
+  {0x1f57, 16, 16, 4440},
+  {0x0, 5, 6, 4440},
+  {0x2f9d2, 16, 16, 4441},
+  {0xc4, 16, 16, 4441},
+  {0x1ea2, 16, 16, 4441},
+  {0x0, 8, 9, 4441},
+  {0x2f8bb, 16, 16, 4442},
+  {0x0, 15, 16, 4442},
+  {0xf910, 16, 16, 4443},
+  {0x0, 0, 1, 4443},
+  {0x0, 0, 1, 4444},
+  {0x0, 3, 4, 4445},
+  {0x0, 0, 1, 4446},
+  {0x0, 1, 8, 4447},
+  {0x1e57, 16, 16, 4454},
+  {0x1e55, 16, 16, 4454},
+  {0x0, 3, 4, 4454},
+  {0xf9e0, 16, 16, 4455},
+  {0x0, 0, 1, 4455},
+  {0x0, 0, 1, 4456},
+  {0x0, 3, 4, 4457},
+  {0x0, 0, 3, 4458},
+  {0x0, 0, 16, 4461},
+  {0xd5, 16, 16, 4477},
+  {0x0, 0, 10, 4477},
+  {0x1ee0, 16, 16, 4487},
+  {0x1eda, 16, 16, 4487},
+  {0x1edc, 16, 16, 4487},
+  {0x0, 0, 1, 4487},
+  {0x0, 0, 1, 4488},
+  {0x0, 3, 4, 4489},
+  {0x0, 3, 4, 4490},
+  {0x0, 8, 9, 4491},
+  {0x22ea, 16, 16, 4492},
+  {0x1ede, 16, 16, 4492},
+  {0x0, 1, 16, 4492},
+  {0x0, 14, 15, 4507},
+  {0x2f852, 16, 16, 4508},
+  {0x0, 0, 12, 4508},
+  {0x2f8b2, 16, 16, 4520},
+  {0x0, 12, 14, 4520},
+  {0x0, 4, 5, 4522},
+  {0x2f9de, 16, 16, 4523},
+  {0x0, 12, 13, 4523},
+  {0x2f88a, 16, 16, 4524},
+  {0x0, 0, 14, 4524},
+  {0xfa32, 16, 16, 4538},
+  {0x0, 0, 1, 4538},
+  {0x0, 0, 1, 4539},
+  {0x0, 3, 4, 4540},
+  {0x0, 0, 1, 4541},
+  {0x0, 7, 8, 4542},
+  {0x1e67, 16, 16, 4543},
+  {0x0, 8, 9, 4543},
+  {0x2f9b8, 16, 16, 4544},
+  {0x0, 9, 10, 4544},
+  {0x2f8de, 16, 16, 4545},
+  {0x1f7c, 16, 16, 4545},
+  {0x0, 2, 3, 4545},
+  {0x1fdf, 16, 16, 4546},
+  {0x0, 6, 7, 4546},
+  {0x0, 11, 12, 4547},
+  {0x2f9a5, 16, 16, 4548},
+  {0x0, 6, 7, 4548},
+  {0xfa01, 16, 16, 4549},
+  {0x0, 9, 10, 4549},
+  {0x2f809, 16, 16, 4550},
+  {0x0, 4, 14, 4550},
+  {0x0, 15, 16, 4560},
+  {0x2f81c, 16, 16, 4561},
+  {0x0, 9, 10, 4561},
+  {0x2f9b7, 16, 16, 4562},
+  {0x0, 12, 15, 4562},
+  {0xf973, 16, 16, 4565},
+  {0x0, 0, 1, 4565},
+  {0x0, 3, 4, 4566},
+  {0x0, 0, 1, 4567},
+  {0x0, 9, 10, 4568},
+  {0x0, 9, 10, 4569},
+  {0x30c0, 16, 16, 4570},
+  {0x0, 3, 5, 4570},
+  {0x1f08, 16, 16, 4572},
+  {0x2f8b3, 16, 16, 4572},
+  {0x1f09, 16, 16, 4572},
+  {0x2f8ba, 16, 16, 4572},
+  {0x0, 0, 1, 4572},
+  {0x0, 0, 1, 4573},
+  {0x0, 3, 4, 4574},
+  {0x0, 0, 5, 4575},
+  {0x0, 0, 2, 4580},
+  {0x1fd2, 16, 16, 4582},
+  {0x390, 16, 16, 4582},
+  {0xfa0c, 16, 16, 4582},
+  {0x0, 0, 1, 4582},
+  {0x0, 0, 1, 4583},
+  {0x0, 3, 4, 4584},
+  {0x0, 0, 1, 4585},
+  {0x0, 1, 2, 4586},
+  {0x1e79, 16, 16, 4587},
+  {0x0, 4, 16, 4587},
+  {0x2f8ad, 16, 16, 4599},
+  {0x0, 2, 3, 4599},
+  {0x0, 15, 16, 4600},
+  {0x2f958, 16, 16, 4601},
+  {0x0, 5, 8, 4601},
+  {0x2f81b, 16, 16, 4604},
+  {0x0, 0, 1, 4604},
+  {0x0, 0, 1, 4605},
+  {0x0, 3, 4, 4606},
+  {0x0, 3, 4, 4607},
+  {0x0, 8, 9, 4608},
+  {0x2275, 16, 16, 4609},
+  {0x0, 0, 13, 4609},
+  {0x148, 16, 16, 4622},
+  {0x0, 0, 15, 4622},
+  {0x0, 14, 15, 4637},
+  {0x2f985, 16, 16, 4638},
+  {0x0, 0, 7, 4638},
+  {0xfa66, 16, 16, 4645},
+  {0xf971, 16, 16, 4645},
+  {0x0, 1, 2, 4645},
+  {0x20b, 16, 16, 4646},
+  {0x0, 0, 1, 4646},
+  {0x0, 0, 1, 4647},
+  {0x0, 3, 4, 4648},
+  {0x0, 0, 5, 4649},
+  {0x0, 2, 3, 4654},
+  {0x1fe6, 16, 16, 4655},
+  {0x0, 2, 3, 4655},
+  {0x1f3f, 16, 16, 4656},
+  {0x0, 7, 8, 4656},
+  {0x0, 1, 2, 4657},
+  {0x0, 0, 1, 4658},
+  {0x0, 0, 1, 4659},
+  {0x0, 15, 16, 4660},
+  {0x0, 7, 9, 4661},
+  {0x0, 0, 1, 4663},
+  {0xf81, 16, 16, 4664},
+  {0x0, 0, 1, 4664},
+  {0x0, 0, 1, 4665},
+  {0x0, 3, 4, 4666},
+  {0x0, 4, 5, 4667},
+  {0x0, 5, 6, 4668},
+  {0x1fb2, 16, 16, 4669},
+  {0x0, 3, 4, 4669},
+  {0x1e04, 16, 16, 4670},
+  {0x0, 1, 2, 4670},
+  {0x2f96d, 16, 16, 4671},
+  {0x0, 0, 16, 4671},
+  {0x2f95b, 16, 16, 4687},
+  {0x2f95a, 16, 16, 4687},
+  {0x1e45, 16, 16, 4687},
+  {0x1f9, 16, 16, 4687},
+  {0x144, 16, 16, 4687},
+  {0x0, 9, 10, 4687},
+  {0x2f9eb, 16, 16, 4688},
+  {0xf1, 16, 16, 4688},
+  {0x0, 0, 1, 4688},
+  {0x0, 0, 1, 4689},
+  {0x0, 3, 4, 4690},
+  {0x0, 0, 1, 4691},
+  {0x0, 2, 7, 4692},
+  {0x1ead, 16, 16, 4697},
+  {0x0, 9, 10, 4697},
+  {0x2f913, 16, 16, 4698},
+  {0x1eb7, 16, 16, 4698},
+  {0x0, 0, 1, 4698},
+  {0x0, 0, 1, 4699},
+  {0x0, 3, 4, 4700},
+  {0x0, 0, 4, 4701},
+  {0x0, 0, 13, 4705},
+  {0x147, 16, 16, 4718},
+  {0x0, 11, 14, 4718},
+  {0xfa09, 16, 16, 4721},
+  {0x0, 8, 9, 4721},
+  {0x2f83d, 16, 16, 4722},
+  {0x0, 10, 12, 4722},
+  {0x0, 7, 8, 4724},
+  {0x2f987, 16, 16, 4725},
+  {0x0, 3, 4, 4725},
+  {0x2f951, 16, 16, 4726},
+  {0x0, 5, 9, 4726},
+  {0x0, 14, 15, 4730},
+  {0x2f910, 16, 16, 4731},
+  {0xfa54, 16, 16, 4731},
+  {0x0, 10, 11, 4731},
+  {0xfa46, 16, 16, 4732},
+  {0x0, 3, 4, 4732},
+  {0x2f86d, 16, 16, 4733},
+  {0x0, 0, 16, 4733},
+  {0x1ecf, 16, 16, 4749},
+  {0xf6, 16, 16, 4749},
+  {0x14d, 16, 16, 4749},
+  {0x0, 3, 4, 4749},
+  {0x2f9a0, 16, 16, 4750},
+  {0x14f, 16, 16, 4750},
+  {0xf3, 16, 16, 4750},
+  {0xf2, 16, 16, 4750},
+  {0xf5, 16, 16, 4750},
+  {0xf4, 16, 16, 4750},
+  {0x0, 5, 6, 4750},
+  {0x2f8c0, 16, 16, 4751},
+  {0x0, 6, 7, 4751},
+  {0x2f841, 16, 16, 4752},
+  {0x0, 0, 1, 4752},
+  {0x0, 0, 1, 4753},
+  {0x0, 3, 4, 4754},
+  {0x0, 4, 5, 4755},
+  {0x0, 5, 6, 4756},
+  {0x1f9d, 16, 16, 4757},
+  {0x0, 15, 16, 4757},
+  {0xf93c, 16, 16, 4758},
+  {0x0, 0, 13, 4758},
+  {0xf9fd, 16, 16, 4771},
+  {0x0, 0, 2, 4771},
+  {0x1f65, 16, 16, 4773},
+  {0x1f63, 16, 16, 4773},
+  {0x2f8ae, 16, 16, 4773},
+  {0x0, 0, 1, 4773},
+  {0x0, 0, 1, 4774},
+  {0x0, 3, 4, 4775},
+  {0x0, 0, 1, 4776},
+  {0x0, 4, 5, 4777},
+  {0x231, 16, 16, 4778},
+  {0x0, 2, 4, 4778},
+  {0x2f942, 16, 16, 4780},
+  {0x2f941, 16, 16, 4780},
+  {0xf951, 16, 16, 4780},
+  {0x0, 8, 9, 4780},
+  {0x2f8ee, 16, 16, 4781},
+  {0x2f819, 16, 16, 4781},
+  {0x20d, 16, 16, 4781},
+  {0x1d2, 16, 16, 4781},
+  {0x151, 16, 16, 4781},
+  {0x0, 0, 1, 4781},
+  {0x0, 0, 1, 4782},
+  {0x0, 3, 4, 4783},
+  {0x0, 0, 3, 4784},
+  {0x0, 3, 4, 4787},
+  {0x1e7f, 16, 16, 4788},
+  {0x0, 14, 15, 4788},
+  {0x2f80c, 16, 16, 4789},
+  {0x2f828, 16, 16, 4789},
+  {0x0, 15, 16, 4789},
+  {0x2f980, 16, 16, 4790},
+  {0x0, 5, 10, 4790},
+  {0x2f931, 16, 16, 4795},
+  {0x0, 14, 15, 4795},
+  {0x2f98d, 16, 16, 4796},
+  {0x0, 9, 10, 4796},
+  {0xfa63, 16, 16, 4797},
+  {0xf994, 16, 16, 4797},
+  {0x0, 14, 16, 4797},
+  {0x2f947, 16, 16, 4799},
+  {0x0, 2, 8, 4799},
+  {0x0, 0, 1, 4805},
+  {0x0, 0, 1, 4806},
+  {0x0, 3, 4, 4807},
+  {0x0, 3, 4, 4808},
+  {0x0, 8, 9, 4809},
+  {0x2289, 16, 16, 4810},
+  {0x0, 13, 14, 4810},
+  {0x0, 1, 2, 4811},
+  {0x2f90d, 16, 16, 4812},
+  {0x0, 7, 8, 4812},
+  {0x2f8a5, 16, 16, 4813},
+  {0x0, 5, 11, 4813},
+  {0xf9a7, 16, 16, 4819},
+  {0x0, 9, 12, 4819},
+  {0x2f813, 16, 16, 4822},
+  {0x0, 8, 10, 4822},
+  {0x0, 15, 16, 4824},
+  {0x2f939, 16, 16, 4825},
+  {0x0, 0, 1, 4825},
+  {0x0, 0, 1, 4826},
+  {0x0, 3, 4, 4827},
+  {0x0, 0, 1, 4828},
+  {0x0, 0, 10, 4829},
+  {0x1ec1, 16, 16, 4839},
+  {0x0, 10, 11, 4839},
+  {0xf911, 16, 16, 4840},
+  {0x2f928, 16, 16, 4840},
+  {0x0, 11, 12, 4840},
+  {0xf9c8, 16, 16, 4841},
+  {0x0, 0, 1, 4841},
+  {0xf962, 16, 16, 4842},
+  {0x0, 14, 15, 4842},
+  {0xf957, 16, 16, 4843},
+  {0x0, 0, 1, 4843},
+  {0x0, 0, 1, 4844},
+  {0x0, 3, 4, 4845},
+  {0x0, 0, 1, 4846},
+  {0x0, 4, 5, 4847},
+  {0x1e1, 16, 16, 4848},
+  {0x0, 1, 2, 4848},
+  {0x1e6e, 16, 16, 4849},
+  {0x0, 10, 11, 4849},
+  {0x2f8aa, 16, 16, 4850},
+  {0x0, 8, 9, 4850},
+  {0xf9c5, 16, 16, 4851},
+  {0x0, 0, 1, 4851},
+  {0x0, 0, 1, 4852},
+  {0x0, 3, 4, 4853},
+  {0x0, 0, 1, 4854},
+  {0x0, 4, 5, 4855},
+  {0x1df, 16, 16, 4856},
+  {0x0, 0, 2, 4856},
+  {0x1f02, 16, 16, 4858},
+  {0x1f04, 16, 16, 4858},
+  {0x0, 14, 15, 4858},
+  {0xf984, 16, 16, 4859},
+  {0x0, 2, 3, 4859},
+  {0x0, 5, 6, 4860},
+  {0x0, 0, 1, 4861},
+  {0x0, 1, 2, 4862},
+  {0x0, 0, 1, 4863},
+  {0x0, 2, 3, 4864},
+  {0x0, 14, 15, 4865},
+  {0x1026, 16, 16, 4866},
+  {0x0, 14, 15, 4866},
+  {0x2f8fa, 16, 16, 4867},
+  {0x2f9ca, 16, 16, 4867},
+  {0x0, 0, 1, 4867},
+  {0x0, 0, 1, 4868},
+  {0x0, 3, 4, 4869},
+  {0x0, 0, 5, 4870},
+  {0x0, 0, 2, 4875},
+  {0x1f25, 16, 16, 4877},
+  {0x0, 11, 16, 4877},
+  {0x2f806, 16, 16, 4882},
+  {0x0, 1, 2, 4882},
+  {0x202, 16, 16, 4883},
+  {0x0, 0, 1, 4883},
+  {0x2f8b7, 16, 16, 4884},
+  {0x0, 2, 3, 4884},
+  {0x2f982, 16, 16, 4885},
+  {0x0, 8, 10, 4885},
+  {0x0, 0, 1, 4887},
+  {0x0, 0, 1, 4888},
+  {0x0, 3, 4, 4889},
+  {0x0, 0, 1, 4890},
+  {0x0, 8, 9, 4891},
+  {0x4ea, 16, 16, 4892},
+  {0x0, 0, 1, 4892},
+  {0xf98f, 16, 16, 4893},
+  {0x0, 13, 15, 4893},
+  {0x0, 13, 14, 4895},
+  {0x2f9e1, 16, 16, 4896},
+  {0x0, 0, 1, 4896},
+  {0x0, 0, 1, 4897},
+  {0x0, 3, 4, 4898},
+  {0x0, 0, 2, 4899},
+  {0x0, 0, 2, 4901},
+  {0x38c, 16, 16, 4903},
+  {0x0, 2, 7, 4903},
+  {0xf90d, 16, 16, 4908},
+  {0x0, 2, 3, 4908},
+  {0x2f875, 16, 16, 4909},
+  {0x0, 14, 15, 4909},
+  {0xf9d2, 16, 16, 4910},
+  {0x0, 10, 11, 4910},
+  {0xf902, 16, 16, 4911},
+  {0x22f, 16, 16, 4911},
+  {0x0, 2, 3, 4911},
+  {0x1f56, 16, 16, 4912},
+  {0x0, 3, 8, 4912},
+  {0x15e, 16, 16, 4917},
+  {0x218, 16, 16, 4917},
+  {0x1e62, 16, 16, 4917},
+  {0x0, 2, 7, 4917},
+  {0xf9ba, 16, 16, 4922},
+  {0xf91b, 16, 16, 4922},
+  {0x0, 3, 10, 4922},
+  {0x0, 6, 7, 4929},
+  {0x2f916, 16, 16, 4930},
+  {0x0, 0, 1, 4930},
+  {0x0, 0, 1, 4931},
+  {0x0, 3, 4, 4932},
+  {0x0, 3, 4, 4933},
+  {0x0, 8, 9, 4934},
+  {0x22ae, 16, 16, 4935},
+  {0x0, 7, 8, 4935},
+  {0x2f973, 16, 16, 4936},
+  {0x0, 0, 1, 4936},
+  {0x0, 0, 1, 4937},
+  {0x0, 3, 4, 4938},
+  {0x0, 4, 5, 4939},
+  {0x0, 5, 6, 4940},
+  {0x1fa6, 16, 16, 4941},
+  {0x0, 0, 1, 4941},
+  {0x0, 0, 1, 4942},
+  {0x0, 3, 4, 4943},
+  {0x0, 0, 1, 4944},
+  {0x0, 0, 2, 4945},
+  {0x1f42, 16, 16, 4947},
+  {0x1f44, 16, 16, 4947},
+  {0x0, 3, 4, 4947},
+  {0x2f843, 16, 16, 4948},
+  {0x0, 10, 11, 4948},
+  {0x0, 3, 4, 4949},
+  {0x2f8ec, 16, 16, 4950},
+  {0x0, 0, 10, 4950},
+  {0x1edd, 16, 16, 4960},
+  {0x1edb, 16, 16, 4960},
+  {0x0, 15, 16, 4960},
+  {0xf9eb, 16, 16, 4961},
+  {0x1ee1, 16, 16, 4961},
+  {0x1edf, 16, 16, 4961},
+  {0x622, 16, 16, 4961},
+  {0x0, 0, 1, 4961},
+  {0x0, 3, 4, 4962},
+  {0x0, 0, 1, 4963},
+  {0x0, 9, 10, 4964},
+  {0x0, 9, 11, 4965},
+  {0x30d3, 16, 16, 4967},
+  {0x0, 1, 4, 4967},
+  {0x0, 12, 13, 4970},
+  {0x2f8a2, 16, 16, 4971},
+  {0x0, 0, 1, 4971},
+  {0xf944, 16, 16, 4972},
+  {0x0, 0, 1, 4972},
+  {0x1e2c, 16, 16, 4973},
+  {0x0, 0, 1, 4973},
+  {0x0, 0, 1, 4974},
+  {0x0, 3, 4, 4975},
+  {0x0, 0, 4, 4976},
+  {0x0, 3, 8, 4980},
+  {0x1e33, 16, 16, 4985},
+  {0x0, 2, 3, 4985},
+  {0x2f888, 16, 16, 4986},
+  {0x0, 4, 5, 4986},
+  {0x2f80f, 16, 16, 4987},
+  {0x0, 0, 10, 4987},
+  {0x0, 14, 15, 4997},
+  {0x2fa13, 16, 16, 4998},
+  {0x0, 2, 3, 4998},
+  {0x2f960, 16, 16, 4999},
+  {0x0, 8, 9, 4999},
+  {0x0, 0, 1, 5000},
+  {0x0, 0, 1, 5001},
+  {0x0, 9, 10, 5002},
+  {0x0, 3, 4, 5003},
+  {0x0, 12, 13, 5004},
+  {0x929, 16, 16, 5005},
+  {0x0, 0, 1, 5005},
+  {0x0, 10, 11, 5006},
+  {0x2f8ca, 16, 16, 5007},
+  {0x0, 0, 1, 5007},
+  {0x0, 0, 1, 5008},
+  {0x0, 3, 4, 5009},
+  {0x0, 0, 5, 5010},
+  {0x0, 2, 6, 5015},
+  {0x1fa8, 16, 16, 5019},
+  {0x0, 0, 1, 5019},
+  {0x0, 0, 1, 5020},
+  {0x0, 3, 4, 5021},
+  {0x0, 4, 5, 5022},
+  {0x0, 5, 6, 5023},
+  {0x1f9e, 16, 16, 5024},
+  {0x0, 0, 1, 5024},
+  {0x0, 3, 4, 5025},
+  {0x0, 0, 1, 5026},
+  {0x0, 9, 10, 5027},
+  {0x0, 9, 10, 5028},
+  {0x30fe, 16, 16, 5029},
+  {0x0, 2, 13, 5029},
+  {0x1e27, 16, 16, 5040},
+  {0x1e23, 16, 16, 5040},
+  {0x125, 16, 16, 5040},
+  {0x0, 4, 5, 5040},
+  {0x2f8f1, 16, 16, 5041},
+  {0x0, 3, 5, 5041},
+  {0x1f60, 16, 16, 5043},
+  {0x0, 4, 5, 5043},
+  {0x2f971, 16, 16, 5044},
+  {0x30d4, 16, 16, 5044},
+  {0x1f61, 16, 16, 5044},
+  {0x0, 0, 1, 5044},
+  {0x0, 3, 4, 5045},
+  {0x0, 0, 1, 5046},
+  {0x0, 9, 10, 5047},
+  {0x0, 9, 10, 5048},
+  {0x304c, 16, 16, 5049},
+  {0x0, 0, 1, 5049},
+  {0x0, 0, 1, 5050},
+  {0x0, 3, 4, 5051},
+  {0x0, 0, 1, 5052},
+  {0x0, 1, 2, 5053},
+  {0x1e78, 16, 16, 5054},
+  {0x0, 0, 1, 5054},
+  {0x0, 3, 4, 5055},
+  {0x0, 0, 1, 5056},
+  {0x0, 9, 10, 5057},
+  {0x0, 9, 11, 5058},
+  {0x30d9, 16, 16, 5060},
+  {0x0, 8, 9, 5060},
+  {0xf9b3, 16, 16, 5061},
+  {0x0, 11, 15, 5061},
+  {0x2f914, 16, 16, 5065},
+  {0x0, 8, 14, 5065},
+  {0xfa5c, 16, 16, 5071},
+  {0x0, 0, 2, 5071},
+  {0x1f34, 16, 16, 5073},
+  {0x2f915, 16, 16, 5073},
+  {0x0, 0, 1, 5073},
+  {0x0, 0, 1, 5074},
+  {0x0, 3, 4, 5075},
+  {0x0, 4, 5, 5076},
+  {0x0, 5, 6, 5077},
+  {0x1f85, 16, 16, 5078},
+  {0x0, 4, 15, 5078},
+  {0x2f907, 16, 16, 5089},
+  {0x0, 2, 3, 5089},
+  {0x2f8bf, 16, 16, 5090},
+  {0x0, 15, 16, 5090},
+  {0xf937, 16, 16, 5091},
+  {0x2126, 0, 1, 5091},
+  {0x0, 0, 1, 5092},
+  {0x0, 3, 4, 5093},
+  {0x0, 0, 5, 5094},
+  {0x0, 0, 2, 5099},
+  {0x1ffa, 16, 16, 5101},
+  {0x38f, 16, 16, 5101},
+  {0x0, 4, 13, 5101},
+  {0x0, 0, 1, 5110},
+  {0x0, 0, 1, 5111},
+  {0x0, 3, 4, 5112},
+  {0x0, 0, 1, 5113},
+  {0x0, 1, 2, 5114},
+  {0x1ff, 16, 16, 5115},
+  {0x0, 0, 1, 5115},
+  {0x0, 0, 1, 5116},
+  {0x0, 3, 4, 5117},
+  {0x0, 4, 5, 5118},
+  {0x0, 5, 6, 5119},
+  {0x1f84, 16, 16, 5120},
+  {0xf9f6, 16, 16, 5120},
+  {0x0, 8, 10, 5120},
+  {0x2329, 16, 16, 5122},
+  {0x232a, 16, 16, 5122},
+  {0x0, 0, 1, 5122},
+  {0x0, 0, 1, 5123},
+  {0x0, 3, 4, 5124},
+  {0x0, 3, 4, 5125},
+  {0x0, 8, 9, 5126},
+  {0x2274, 16, 16, 5127},
+  {0x30da, 16, 16, 5127},
+  {0x0, 4, 13, 5127},
+  {0x0, 0, 1, 5136},
+  {0x0, 0, 1, 5137},
+  {0x0, 3, 4, 5138},
+  {0x0, 0, 1, 5139},
+  {0x0, 0, 10, 5140},
+  {0x1ed4, 16, 16, 5150},
+  {0x0, 4, 5, 5150},
+  {0xfa34, 16, 16, 5151},
+  {0x1ed0, 16, 16, 5151},
+  {0x1ed2, 16, 16, 5151},
+  {0x1ed6, 16, 16, 5151},
+  {0x2f900, 16, 16, 5151},
+  {0x0, 4, 5, 5151},
+  {0x2f940, 16, 16, 5152},
+  {0x0, 0, 1, 5152},
+  {0x0, 0, 1, 5153},
+  {0x0, 3, 4, 5154},
+  {0x0, 0, 1, 5155},
+  {0x0, 1, 9, 5156},
+  {0x1e4e, 16, 16, 5164},
+  {0x1e4c, 16, 16, 5164},
+  {0x22c, 16, 16, 5164},
+  {0x0, 9, 15, 5164},
+  {0x2fa18, 16, 16, 5170},
+  {0x0, 12, 13, 5170},
+  {0x0, 8, 9, 5171},
+  {0x2f86c, 16, 16, 5172},
+  {0x0, 7, 8, 5172},
+  {0x2fa0f, 16, 16, 5173},
+  {0x0, 1, 3, 5173},
+  {0x0, 0, 1, 5175},
+  {0x0, 0, 1, 5176},
+  {0x0, 3, 4, 5177},
+  {0x0, 3, 4, 5178},
+  {0x0, 8, 9, 5179},
+  {0x22e2, 16, 16, 5180},
+  {0x0, 4, 5, 5180},
+  {0xfa06, 16, 16, 5181},
+  {0x0, 0, 1, 5181},
+  {0x0, 0, 1, 5182},
+  {0x0, 3, 4, 5183},
+  {0x0, 0, 4, 5184},
+  {0x0, 1, 16, 5188},
+  {0x155, 16, 16, 5203},
+  {0x0, 8, 9, 5203},
+  {0xfa3e, 16, 16, 5204},
+  {0x0, 0, 1, 5204},
+  {0xf93d, 16, 16, 5205},
+  {0x0, 0, 8, 5205},
+  {0x0, 0, 1, 5213},
+  {0x0, 0, 1, 5214},
+  {0x0, 3, 4, 5215},
+  {0x0, 0, 3, 5216},
+  {0x0, 3, 4, 5219},
+  {0x1ef1, 16, 16, 5220},
+  {0x0, 6, 7, 5220},
+  {0x2f935, 16, 16, 5221},
+  {0x2fa17, 16, 16, 5221},
+  {0x0, 14, 15, 5221},
+  {0xfa48, 16, 16, 5222},
+  {0x0, 15, 16, 5222},
+  {0xf939, 16, 16, 5223},
+  {0x0, 0, 1, 5223},
+  {0x0, 0, 1, 5224},
+  {0x0, 3, 4, 5225},
+  {0x0, 0, 1, 5226},
+  {0x0, 12, 13, 5227},
+  {0x1ee, 16, 16, 5228},
+  {0x0, 8, 9, 5228},
+  {0x2fa11, 16, 16, 5229},
+  {0x0, 8, 9, 5229},
+  {0x2f97e, 16, 16, 5230},
+  {0x0, 4, 5, 5230},
+  {0xfa12, 16, 16, 5231},
+  {0x0, 0, 1, 5231},
+  {0x0, 3, 4, 5232},
+  {0x0, 0, 1, 5233},
+  {0x0, 9, 10, 5234},
+  {0x0, 9, 10, 5235},
+  {0x305c, 16, 16, 5236},
+  {0x0, 10, 11, 5236},
+  {0x2f954, 16, 16, 5237},
+  {0x0, 7, 13, 5237},
+  {0x1e6a, 16, 16, 5243},
+  {0x0, 0, 1, 5243},
+  {0x0, 0, 1, 5244},
+  {0x0, 3, 4, 5245},
+  {0x0, 0, 1, 5246},
+  {0x0, 1, 2, 5247},
+  {0x344, 16, 16, 5248},
+  {0x0, 0, 1, 5248},
+  {0x0, 0, 1, 5249},
+  {0x0, 3, 4, 5250},
+  {0x0, 0, 1, 5251},
+  {0x0, 0, 2, 5252},
+  {0x1f45, 16, 16, 5254},
+  {0x1f43, 16, 16, 5254},
+  {0x0, 0, 1, 5254},
+  {0x0, 0, 1, 5255},
+  {0x0, 3, 4, 5256},
+  {0x0, 0, 4, 5257},
+  {0x0, 1, 2, 5261},
+  {0x1e94, 16, 16, 5262},
+  {0x0, 15, 16, 5262},
+  {0xf9bd, 16, 16, 5263},
+  {0x0, 1, 13, 5263},
+  {0xfa43, 16, 16, 5275},
+  {0x0, 0, 1, 5275},
+  {0x0, 0, 1, 5276},
+  {0x0, 3, 4, 5277},
+  {0x0, 0, 1, 5278},
+  {0x0, 0, 2, 5279},
+  {0x1e51, 16, 16, 5281},
+  {0x1e53, 16, 16, 5281},
+  {0x0, 3, 4, 5281},
+  {0x2f889, 16, 16, 5282},
+  {0x0, 3, 9, 5282},
+  {0x104, 16, 16, 5288},
+  {0x164, 16, 16, 5288},
+  {0x0, 7, 8, 5288},
+  {0x2fa05, 16, 16, 5289},
+  {0x1ea0, 16, 16, 5289},
+  {0x1e00, 16, 16, 5289},
+  {0x0, 13, 14, 5289},
+  {0x0, 0, 1, 5290},
+  {0x0, 3, 4, 5291},
+  {0x0, 0, 1, 5292},
+  {0x0, 9, 10, 5293},
+  {0x0, 9, 10, 5294},
+  {0x309e, 16, 16, 5295},
+  {0x0, 2, 3, 5295},
+  {0x2f840, 16, 16, 5296},
+  {0x0, 10, 11, 5296},
+  {0x2f948, 16, 16, 5297},
+  {0x2f8d5, 16, 16, 5297},
+  {0x0, 11, 12, 5297},
+  {0xf9f7, 16, 16, 5298},
+  {0x0, 0, 1, 5298},
+  {0x0, 0, 1, 5299},
+  {0x0, 3, 4, 5300},
+  {0x0, 0, 1, 5301},
+  {0x0, 6, 9, 5302},
+  {0x4c1, 16, 16, 5305},
+  {0x1f24, 16, 16, 5305},
+  {0x0, 0, 1, 5305},
+  {0x0, 0, 1, 5306},
+  {0x0, 3, 4, 5307},
+  {0x0, 0, 5, 5308},
+  {0x0, 2, 6, 5313},
+  {0x1f6f, 16, 16, 5317},
+  {0x4dc, 16, 16, 5317},
+  {0x0, 0, 1, 5317},
+  {0x0, 0, 1, 5318},
+  {0x0, 3, 4, 5319},
+  {0x0, 0, 1, 5320},
+  {0x0, 1, 2, 5321},
+  {0x1fe, 16, 16, 5322},
+  {0x1fa9, 16, 16, 5322},
+  {0x0, 13, 14, 5322},
+  {0x2f99b, 16, 16, 5323},
+  {0x0, 0, 1, 5323},
+  {0x0, 0, 1, 5324},
+  {0x0, 3, 4, 5325},
+  {0x0, 3, 4, 5326},
+  {0x0, 8, 9, 5327},
+  {0x2204, 16, 16, 5328},
+  {0x0, 10, 12, 5328},
+  {0x0, 8, 9, 5330},
+  {0x2f92d, 16, 16, 5331},
+  {0x0, 0, 1, 5331},
+  {0x0, 0, 1, 5332},
+  {0x0, 3, 4, 5333},
+  {0x0, 0, 1, 5334},
+  {0x0, 0, 10, 5335},
+  {0x1ec2, 16, 16, 5345},
+  {0x1ebe, 16, 16, 5345},
+  {0x1ec0, 16, 16, 5345},
+  {0x1ec4, 16, 16, 5345},
+  {0x0, 2, 3, 5345},
+  {0x2f9e0, 16, 16, 5346},
+  {0x0, 2, 3, 5346},
+  {0x0, 12, 13, 5347},
+  {0x2f834, 16, 16, 5348},
+  {0x0, 7, 9, 5348},
+  {0x2f904, 16, 16, 5350},
+  {0x0, 6, 7, 5350},
+  {0x0, 0, 1, 5351},
+  {0x0, 0, 1, 5352},
+  {0x0, 3, 4, 5353},
+  {0x0, 0, 1, 5354},
+  {0x0, 8, 9, 5355},
+  {0x457, 16, 16, 5356},
+  {0x0, 0, 1, 5356},
+  {0x0, 0, 1, 5357},
+  {0x0, 3, 4, 5358},
+  {0x0, 0, 2, 5359},
+  {0x0, 0, 2, 5361},
+  {0x3ad, 16, 16, 5363},
+  {0x0, 0, 14, 5363},
+  {0x0, 8, 9, 5377},
+  {0x2f8eb, 16, 16, 5378},
+  {0x0, 0, 1, 5378},
+  {0x0, 0, 1, 5379},
+  {0x0, 3, 4, 5380},
+  {0x0, 0, 3, 5381},
+  {0x0, 3, 8, 5384},
+  {0x1e63, 16, 16, 5389},
+  {0x15f, 16, 16, 5389},
+  {0x219, 16, 16, 5389},
+  {0x0, 0, 1, 5389},
+  {0x0, 0, 1, 5390},
+  {0x0, 3, 4, 5391},
+  {0x0, 3, 4, 5392},
+  {0x0, 8, 9, 5393},
+  {0x2285, 16, 16, 5394},
+  {0x4ef, 16, 16, 5394},
+  {0xcf, 16, 16, 5394},
+  {0x0, 0, 1, 5394},
+  {0x0, 0, 1, 5395},
+  {0x0, 13, 14, 5396},
+  {0x0, 12, 14, 5397},
+  {0x0, 15, 16, 5399},
+  {0xdde, 16, 16, 5400},
+  {0x4f1, 16, 16, 5400},
+  {0x130, 16, 16, 5400},
+  {0x12a, 16, 16, 5400},
+  {0xce, 16, 16, 5400},
+  {0x128, 16, 16, 5400},
+  {0xcc, 16, 16, 5400},
+  {0xcd, 16, 16, 5400},
+  {0x0, 10, 11, 5400},
+  {0x2f8ea, 16, 16, 5401},
+  {0x0, 2, 6, 5401},
+  {0x1fc3, 16, 16, 5405},
+  {0x0, 7, 8, 5405},
+  {0x1e02, 16, 16, 5406},
+  {0x1fc6, 16, 16, 5406},
+  {0x0, 2, 4, 5406},
+  {0x0, 0, 1, 5408},
+  {0x0, 0, 1, 5409},
+  {0x0, 3, 4, 5410},
+  {0x0, 0, 1, 5411},
+  {0x0, 0, 10, 5412},
+  {0x1eaf, 16, 16, 5422},
+  {0x0, 2, 16, 5422},
+  {0x2fa02, 16, 16, 5436},
+  {0x0, 2, 6, 5436},
+  {0x1fb3, 16, 16, 5440},
+  {0x0, 0, 1, 5440},
+  {0x0, 0, 1, 5441},
+  {0x0, 3, 4, 5442},
+  {0x0, 0, 1, 5443},
+  {0x0, 8, 9, 5444},
+  {0x4f4, 16, 16, 5445},
+  {0x1fb6, 16, 16, 5445},
+  {0x0, 6, 7, 5445},
+  {0xfa1c, 16, 16, 5446},
+  {0x0, 2, 3, 5446},
+  {0x1f37, 16, 16, 5447},
+  {0x0, 13, 14, 5447},
+  {0x2f815, 16, 16, 5448},
+  {0x0, 11, 12, 5448},
+  {0x2f855, 16, 16, 5449},
+  {0x0, 12, 14, 5449},
+  {0x2f8fd, 16, 16, 5451},
+  {0x4f3, 16, 16, 5451},
+  {0xf968, 16, 16, 5451},
+  {0x208, 16, 16, 5451},
+  {0x0, 1, 2, 5451},
+  {0xf90a, 16, 16, 5452},
+  {0x1cf, 16, 16, 5452},
+  {0x0, 14, 15, 5452},
+  {0xf9c6, 16, 16, 5453},
+  {0xfa2a, 16, 16, 5453},
+  {0x0, 3, 5, 5453},
+  {0x1f68, 16, 16, 5455},
+  {0x1f69, 16, 16, 5455},
+  {0x0, 1, 5, 5455},
+  {0x2f98c, 16, 16, 5459},
+  {0x2f893, 16, 16, 5459},
+  {0x0, 8, 9, 5459},
+  {0xf926, 16, 16, 5460},
+  {0x0, 3, 9, 5460},
+  {0x1ecd, 16, 16, 5466},
+  {0x0, 0, 1, 5466},
+  {0x0, 3, 4, 5467},
+  {0x0, 0, 1, 5468},
+  {0x0, 9, 10, 5469},
+  {0x0, 9, 10, 5470},
+  {0x3052, 16, 16, 5471},
+  {0x1eb, 16, 16, 5471},
+  {0x0, 0, 10, 5471},
+  {0xf975, 16, 16, 5481},
+  {0x2f8c1, 16, 16, 5481},
+  {0x0, 0, 1, 5481},
+  {0x0, 0, 1, 5482},
+  {0x0, 3, 4, 5483},
+  {0x0, 0, 4, 5484},
+  {0x0, 7, 13, 5488},
+  {0x1e0a, 16, 16, 5494},
+  {0x0, 0, 1, 5494},
+  {0x2f9dc, 16, 16, 5495},
+  {0x0, 0, 1, 5495},
+  {0x1e1b, 16, 16, 5496},
+  {0x0, 2, 15, 5496},
+  {0xf952, 16, 16, 5509},
+  {0x0, 13, 14, 5509},
+  {0xfa1e, 16, 16, 5510},
+  {0x0, 4, 5, 5510},
+  {0x2f8d1, 16, 16, 5511},
+  {0x10e, 16, 16, 5511},
+  {0x0, 14, 15, 5511},
+  {0xf977, 16, 16, 5512},
+  {0x0, 0, 1, 5512},
+  {0xfa60, 16, 16, 5513},
+  {0x0, 10, 12, 5513},
+  {0x0, 1, 2, 5515},
+  {0x2f93b, 16, 16, 5516},
+  {0x0, 3, 4, 5516},
+  {0x1e7d, 16, 16, 5517},
+  {0x0, 0, 1, 5517},
+  {0x0, 0, 1, 5518},
+  {0x0, 3, 4, 5519},
+  {0x0, 4, 5, 5520},
+  {0x0, 5, 6, 5521},
+  {0x1fac, 16, 16, 5522},
+  {0x0, 1, 2, 5522},
+  {0x0, 8, 9, 5523},
+  {0x2f871, 16, 16, 5524},
+  {0x0, 10, 13, 5524},
+  {0xf947, 16, 16, 5527},
+  {0x2f950, 16, 16, 5527},
+  {0x0, 0, 1, 5527},
+  {0x0, 0, 1, 5528},
+  {0x0, 3, 4, 5529},
+  {0x0, 4, 5, 5530},
+  {0x0, 5, 6, 5531},
+  {0x1ff7, 16, 16, 5532},
+  {0x0, 10, 15, 5532},
+  {0xf96c, 16, 16, 5537},
+  {0x0, 0, 1, 5537},
+  {0x0, 0, 1, 5538},
+  {0x0, 3, 4, 5539},
+  {0x0, 0, 1, 5540},
+  {0x0, 8, 9, 5541},
+  {0x4ec, 16, 16, 5542},
+  {0xfa10, 16, 16, 5542},
+  {0x0, 0, 10, 5542},
+  {0x0, 10, 11, 5552},
+  {0x2f9fb, 16, 16, 5553},
+  {0xf92f, 16, 16, 5553},
+  {0x0, 6, 7, 5553},
+  {0xf98b, 16, 16, 5554},
+  {0x0, 4, 5, 5554},
+  {0x2f8e6, 16, 16, 5555},
+  {0x0, 0, 1, 5555},
+  {0x0, 0, 1, 5556},
+  {0x0, 3, 4, 5557},
+  {0x0, 4, 5, 5558},
+  {0x0, 5, 6, 5559},
+  {0x1fab, 16, 16, 5560},
+  {0x0, 7, 8, 5560},
+  {0x0, 7, 8, 5561},
+  {0x2f9f1, 16, 16, 5562},
+  {0x0, 0, 1, 5562},
+  {0x0, 0, 1, 5563},
+  {0x0, 3, 4, 5564},
+  {0x0, 0, 1, 5565},
+  {0x0, 4, 5, 5566},
+  {0x22a, 16, 16, 5567},
+  {0x0, 0, 1, 5567},
+  {0x0, 0, 1, 5568},
+  {0x0, 3, 4, 5569},
+  {0x0, 3, 4, 5570},
+  {0x0, 8, 9, 5571},
+  {0x219a, 16, 16, 5572},
+  {0xf92e, 16, 16, 5572},
+  {0xf965, 16, 16, 5572},
+  {0x0, 0, 1, 5572},
+  {0x0, 0, 1, 5573},
+  {0x0, 3, 4, 5574},
+  {0x0, 0, 4, 5575},
+  {0x0, 7, 13, 5579},
+  {0x165, 16, 16, 5585},
+  {0x0, 2, 6, 5585},
+  {0x1f99, 16, 16, 5589},
+  {0x1f2f, 16, 16, 5589},
+  {0x0, 0, 1, 5589},
+  {0x0, 0, 1, 5590},
+  {0x0, 3, 4, 5591},
+  {0x0, 0, 1, 5592},
+  {0x0, 8, 9, 5593},
+  {0x4de, 16, 16, 5594},
+  {0x0, 14, 15, 5594},
+  {0xfa1d, 16, 16, 5595},
+  {0x1ec3, 16, 16, 5595},
+  {0x0, 0, 1, 5595},
+  {0x0, 0, 1, 5596},
+  {0x0, 3, 4, 5597},
+  {0x0, 0, 2, 5598},
+  {0x0, 0, 2, 5600},
+  {0x1f78, 16, 16, 5602},
+  {0x3cc, 16, 16, 5602},
+  {0x1ec5, 16, 16, 5602},
+  {0x1ebf, 16, 16, 5602},
+  {0x0, 11, 12, 5602},
+  {0x2fa1c, 16, 16, 5603},
+  {0x0, 3, 15, 5603},
+  {0x2f8db, 16, 16, 5615},
+  {0x0, 1, 2, 5615},
+  {0xf904, 16, 16, 5616},
+  {0x0, 3, 4, 5616},
+  {0x1e92, 16, 16, 5617},
+  {0x0, 1, 2, 5617},
+  {0x2f9c1, 16, 16, 5618},
+  {0x1e6b, 16, 16, 5618},
+  {0x1e97, 16, 16, 5618},
+  {0x0, 0, 1, 5618},
+  {0x0, 0, 1, 5619},
+  {0x0, 3, 4, 5620},
+  {0x0, 4, 5, 5621},
+  {0x0, 5, 6, 5622},
+  {0x1ff2, 16, 16, 5623},
+  {0x0, 0, 1, 5623},
+  {0x0, 0, 1, 5624},
+  {0x0, 3, 4, 5625},
+  {0x0, 0, 2, 5626},
+  {0x0, 0, 9, 5628},
+  {0x3aa, 16, 16, 5637},
+  {0x0, 0, 1, 5637},
+  {0x0, 0, 1, 5638},
+  {0x0, 3, 4, 5639},
+  {0x0, 0, 1, 5640},
+  {0x0, 6, 9, 5641},
+  {0x4c2, 16, 16, 5644},
+  {0x4dd, 16, 16, 5644},
+  {0x0, 8, 9, 5644},
+  {0x2f885, 16, 16, 5645},
+  {0x1fda, 16, 16, 5645},
+  {0x38a, 16, 16, 5645},
+  {0x1fd8, 16, 16, 5645},
+  {0x1fd9, 16, 16, 5645},
+  {0x0, 5, 10, 5645},
+  {0xf9a3, 16, 16, 5650},
+  {0x0, 0, 1, 5650},
+  {0xf921, 16, 16, 5651},
+  {0x2f89f, 16, 16, 5651},
+  {0x0, 0, 1, 5651},
+  {0x0, 0, 1, 5652},
+  {0x0, 3, 4, 5653},
+  {0x0, 3, 4, 5654},
+  {0x0, 8, 9, 5655},
+  {0x2288, 16, 16, 5656},
+  {0x0, 0, 1, 5656},
+  {0x0, 0, 1, 5657},
+  {0x0, 3, 4, 5658},
+  {0x0, 0, 4, 5659},
+  {0x0, 1, 12, 5663},
+  {0x1b0, 16, 16, 5674},
+  {0xf9aa, 16, 16, 5674},
+  {0x0, 2, 3, 5674},
+  {0x0, 0, 1, 5675},
+  {0x0, 0, 1, 5676},
+  {0x0, 3, 4, 5677},
+  {0x0, 0, 1, 5678},
+  {0x0, 12, 13, 5679},
+  {0x1ef, 16, 16, 5680},
+  {0x217, 16, 16, 5680},
+  {0x0, 11, 12, 5680},
+  {0x2f9bd, 16, 16, 5681},
+  {0x0, 0, 1, 5681},
+  {0x0, 0, 1, 5682},
+  {0x0, 3, 4, 5683},
+  {0x0, 0, 4, 5684},
+  {0x0, 0, 1, 5688},
+  {0x1e74, 16, 16, 5689},
+  {0x0, 0, 1, 5689},
+  {0x0, 0, 1, 5690},
+  {0x0, 3, 4, 5691},
+  {0x0, 0, 1, 5692},
+  {0x0, 0, 10, 5693},
+  {0x1eb0, 16, 16, 5703},
+  {0x1eae, 16, 16, 5703},
+  {0x1eb4, 16, 16, 5703},
+  {0x1eb2, 16, 16, 5703},
+  {0x0, 8, 9, 5703},
+  {0x2f972, 16, 16, 5704},
+  {0x0, 15, 16, 5704},
+  {0x2f837, 16, 16, 5705},
+  {0x0, 0, 1, 5705},
+  {0x0, 0, 1, 5706},
+  {0x0, 3, 4, 5707},
+  {0x0, 4, 5, 5708},
+  {0x0, 5, 6, 5709},
+  {0x1fa7, 16, 16, 5710},
+  {0x0, 0, 1, 5710},
+  {0x0, 3, 4, 5711},
+  {0x0, 0, 1, 5712},
+  {0x0, 9, 10, 5713},
+  {0x0, 9, 10, 5714},
+  {0x305a, 16, 16, 5715},
+  {0x0, 1, 13, 5715},
+  {0x1e9, 16, 16, 5727},
+  {0x0, 15, 16, 5727},
+  {0x2f908, 16, 16, 5728},
+  {0x0, 15, 16, 5728},
+  {0x2f8fc, 16, 16, 5729},
+  {0xfa51, 16, 16, 5729},
+  {0x0, 13, 14, 5729},
+  {0x2f8e7, 16, 16, 5730},
+  {0x0, 5, 6, 5730},
+  {0x1fbc, 16, 16, 5731},
+  {0x0, 10, 11, 5731},
+  {0x2f8a1, 16, 16, 5732},
+  {0x0, 1, 14, 5732},
+  {0xfa26, 16, 16, 5745},
+  {0x0, 11, 15, 5745},
+  {0x0, 0, 1, 5749},
+  {0x0, 0, 1, 5750},
+  {0x0, 3, 4, 5751},
+  {0x0, 3, 4, 5752},
+  {0x0, 8, 9, 5753},
+  {0x2260, 16, 16, 5754},
+  {0x0, 3, 4, 5754},
+  {0x0, 12, 13, 5755},
+  {0x2f997, 16, 16, 5756},
+  {0x0, 4, 5, 5756},
+  {0x2f853, 16, 16, 5757},
+  {0x3076, 16, 16, 5757},
+  {0x0, 12, 13, 5757},
+  {0xf92b, 16, 16, 5758},
+  {0x0, 2, 3, 5758},
+  {0x0, 2, 3, 5759},
+  {0x2f803, 16, 16, 5760},
+  {0x0, 1, 2, 5760},
+  {0x20a, 16, 16, 5761},
+  {0x0, 0, 1, 5761},
+  {0x0, 0, 1, 5762},
+  {0x0, 12, 13, 5763},
+  {0x0, 12, 14, 5764},
+  {0x0, 2, 3, 5766},
+  {0xcca, 16, 16, 5767},
+  {0x0, 8, 9, 5767},
+  {0x2f865, 16, 16, 5768},
+  {0x1e31, 16, 16, 5768},
+  {0x0, 3, 4, 5768},
+  {0x0, 10, 11, 5769},
+  {0x2f80d, 16, 16, 5770},
+  {0x0, 2, 8, 5770},
+  {0x2f817, 16, 16, 5776},
+  {0x2f8d2, 16, 16, 5776},
+  {0x2f9e3, 16, 16, 5776},
+  {0x0, 0, 2, 5776},
+  {0x1f3c, 16, 16, 5778},
+  {0x1f3a, 16, 16, 5778},
+  {0x0, 6, 8, 5778},
+  {0xb48, 16, 16, 5780},
+  {0xb4c, 16, 16, 5780},
+  {0x0, 0, 1, 5780},
+  {0x0, 0, 1, 5781},
+  {0x0, 3, 4, 5782},
+  {0x0, 3, 4, 5783},
+  {0x0, 8, 9, 5784},
+  {0x2280, 16, 16, 5785},
+  {0x0, 0, 1, 5785},
+  {0x0, 3, 4, 5786},
+  {0x0, 0, 1, 5787},
+  {0x0, 9, 10, 5788},
+  {0x0, 9, 10, 5789},
+  {0x30f4, 16, 16, 5790},
+  {0x0, 6, 8, 5790},
+  {0xf9b2, 16, 16, 5792},
+  {0x0, 3, 8, 5792},
+  {0x1e5b, 16, 16, 5797},
+  {0x0, 0, 1, 5797},
+  {0x0, 0, 1, 5798},
+  {0x0, 3, 4, 5799},
+  {0x0, 0, 1, 5800},
+  {0x0, 8, 9, 5801},
+  {0x4f5, 16, 16, 5802},
+  {0x157, 16, 16, 5802},
+  {0x0, 9, 10, 5802},
+  {0x2f9c2, 16, 16, 5803},
+  {0x0, 5, 6, 5803},
+  {0x2f988, 16, 16, 5804},
+  {0x0, 0, 1, 5804},
+  {0x0, 0, 1, 5805},
+  {0x0, 3, 4, 5806},
+  {0x0, 0, 1, 5807},
+  {0x0, 0, 9, 5808},
+  {0x40d, 16, 16, 5817},
+  {0x0, 0, 1, 5817},
+  {0x0, 0, 1, 5818},
+  {0x0, 3, 4, 5819},
+  {0x0, 0, 1, 5820},
+  {0x0, 1, 8, 5821},
+  {0x1e56, 16, 16, 5828},
+  {0x1e54, 16, 16, 5828},
+  {0x0, 2, 9, 5828},
+  {0x2f83e, 16, 16, 5835},
+  {0x0, 0, 1, 5835},
+  {0x0, 0, 1, 5836},
+  {0x0, 3, 4, 5837},
+  {0x0, 4, 5, 5838},
+  {0x0, 5, 6, 5839},
+  {0x1fa2, 16, 16, 5840},
+  {0xf980, 16, 16, 5840},
+  {0x0, 10, 11, 5840},
+  {0x0, 7, 8, 5841},
+  {0x2f8f0, 16, 16, 5842},
+  {0x0, 14, 15, 5842},
+  {0xd4a, 16, 16, 5843},
+  {0x0, 6, 15, 5843},
+  {0x2f8ff, 16, 16, 5852},
+  {0x0, 0, 1, 5852},
+  {0x0, 0, 1, 5853},
+  {0x0, 3, 4, 5854},
+  {0x0, 0, 3, 5855},
+  {0x0, 3, 4, 5858},
+  {0x1e89, 16, 16, 5859},
+  {0x0, 0, 1, 5859},
+  {0x0, 0, 1, 5860},
+  {0x0, 9, 10, 5861},
+  {0x0, 3, 4, 5862},
+  {0x0, 12, 13, 5863},
+  {0x934, 16, 16, 5864},
+  {0x0, 2, 3, 5864},
+  {0x2f8ac, 16, 16, 5865},
+  {0x0, 4, 5, 5865},
+  {0x2f9ac, 16, 16, 5866},
+  {0x0, 11, 12, 5866},
+  {0x2f816, 16, 16, 5867},
+  {0x0, 14, 15, 5867},
+  {0x2f911, 16, 16, 5868},
+  {0x0, 8, 9, 5868},
+  {0x0, 6, 7, 5869},
+  {0x2f96b, 16, 16, 5870},
+  {0x1e15, 16, 16, 5870},
+  {0x0, 3, 4, 5870},
+  {0x1e05, 16, 16, 5871},
+  {0x0, 8, 9, 5871},
+  {0x2f93f, 16, 16, 5872},
+  {0x0, 8, 9, 5872},
+  {0x2f8d0, 16, 16, 5873},
+  {0x0, 0, 1, 5873},
+  {0x0, 0, 1, 5874},
+  {0x0, 6, 7, 5875},
+  {0x0, 5, 6, 5876},
+  {0x0, 4, 5, 5877},
+  {0x6d3, 16, 16, 5878},
+  {0x0, 1, 2, 5878},
+  {0x1e0e, 16, 16, 5879},
+  {0x0, 7, 10, 5879},
+  {0xfa33, 16, 16, 5882},
+  {0x0, 0, 1, 5882},
+  {0x0, 0, 1, 5883},
+  {0x0, 3, 4, 5884},
+  {0x0, 3, 4, 5885},
+  {0x0, 8, 9, 5886},
+  {0x2279, 16, 16, 5887},
+  {0x0, 2, 12, 5887},
+  {0x0, 1, 2, 5897},
+  {0x2f9b0, 16, 16, 5898},
+  {0x0, 0, 1, 5898},
+  {0xfa39, 16, 16, 5899},
+  {0x2f825, 16, 16, 5899},
+  {0x0, 3, 4, 5899},
+  {0x2f983, 16, 16, 5900},
+  {0xfa05, 16, 16, 5900},
+  {0x0, 9, 10, 5900},
+  {0xf916, 16, 16, 5901},
+  {0xf915, 16, 16, 5901},
+  {0x0, 12, 13, 5901},
+  {0xf908, 16, 16, 5902},
+  {0x0, 9, 13, 5902},
+  {0xf955, 16, 16, 5906},
+  {0x0, 14, 15, 5906},
+  {0xf9e1, 16, 16, 5907},
+  {0x2f8d3, 16, 16, 5907},
+  {0x0, 8, 9, 5907},
+  {0x2f93c, 16, 16, 5908},
+  {0x0, 0, 1, 5908},
+  {0x0, 0, 1, 5909},
+  {0x0, 3, 4, 5910},
+  {0x0, 0, 3, 5911},
+  {0x0, 2, 13, 5914},
+  {0x21e, 16, 16, 5925},
+  {0x0, 0, 1, 5925},
+  {0x0, 0, 1, 5926},
+  {0x0, 3, 4, 5927},
+  {0x0, 0, 1, 5928},
+  {0x0, 6, 9, 5929},
+  {0x4d0, 16, 16, 5932},
+  {0x0, 6, 7, 5932},
+  {0x0, 6, 7, 5933},
+  {0x2f9cc, 16, 16, 5934},
+  {0x0, 10, 11, 5934},
+  {0xf985, 16, 16, 5935},
+  {0x4d2, 16, 16, 5935},
+  {0x0, 3, 4, 5935},
+  {0x2f99a, 16, 16, 5936},
+  {0x1fd3, 16, 16, 5936},
+  {0x0, 4, 6, 5936},
+  {0x0, 0, 1, 5938},
+  {0x0, 0, 1, 5939},
+  {0x0, 3, 4, 5940},
+  {0x0, 0, 1, 5941},
+  {0x0, 15, 16, 5942},
+  {0x477, 16, 16, 5943},
+  {0x1e26, 16, 16, 5943},
+  {0x1e22, 16, 16, 5943},
+  {0x124, 16, 16, 5943},
+  {0xf979, 16, 16, 5943},
+  {0x0, 0, 1, 5943},
+  {0x2f93a, 16, 16, 5944},
+  {0xfa49, 16, 16, 5944},
+  {0x0, 8, 9, 5944},
+  {0xf900, 16, 16, 5945},
+  {0x0, 4, 5, 5945},
+  {0xf924, 16, 16, 5946},
+  {0x1f23, 16, 16, 5946},
+  {0x0, 5, 6, 5946},
+  {0x2f925, 16, 16, 5947},
+  {0x0, 4, 13, 5947},
+  {0x2f818, 16, 16, 5956},
+  {0x0, 10, 11, 5956},
+  {0x2f979, 16, 16, 5957},
+  {0x0, 0, 1, 5957},
+  {0x0, 0, 1, 5958},
+  {0x0, 3, 4, 5959},
+  {0x0, 0, 1, 5960},
+  {0x0, 2, 3, 5961},
+  {0x1ec6, 16, 16, 5962},
+  {0x0, 2, 3, 5962},
+  {0x2f895, 16, 16, 5963},
+  {0x0, 6, 7, 5963},
+  {0x0, 0, 1, 5964},
+  {0x0, 0, 1, 5965},
+  {0x0, 3, 4, 5966},
+  {0x0, 0, 1, 5967},
+  {0x0, 8, 9, 5968},
+  {0x407, 16, 16, 5969},
+  {0xf949, 16, 16, 5969},
+  {0x0, 0, 10, 5969},
+  {0x1eed, 16, 16, 5979},
+  {0x0, 5, 12, 5979},
+  {0x2f839, 16, 16, 5986},
+  {0x1eeb, 16, 16, 5986},
+  {0x1ee9, 16, 16, 5986},
+  {0x0, 3, 5, 5986},
+  {0x1f38, 16, 16, 5988},
+  {0x1eef, 16, 16, 5988},
+  {0x1f39, 16, 16, 5988},
+  {0x0, 0, 10, 5988},
+  {0x2f962, 16, 16, 5998},
+  {0xfa56, 16, 16, 5998},
+  {0x0, 3, 4, 5998},
+  {0x2f87c, 16, 16, 5999},
+  {0x2f963, 16, 16, 5999},
+  {0x0, 0, 1, 5999},
+  {0x0, 0, 1, 6000},
+  {0x0, 3, 4, 6001},
+  {0x0, 0, 1, 6002},
+  {0x0, 1, 5, 6003},
+  {0x1e2, 16, 16, 6007},
+  {0x1fc, 16, 16, 6007},
+  {0x0, 7, 8, 6007},
+  {0xf9f2, 16, 16, 6008},
+  {0xf906, 16, 16, 6008},
+  {0x0, 13, 14, 6008},
+  {0x2f886, 16, 16, 6009},
+  {0x0, 15, 16, 6009},
+  {0xf927, 16, 16, 6010},
+  {0x0, 12, 13, 6010},
+  {0x2f92a, 16, 16, 6011},
+  {0x0, 3, 5, 6011},
+  {0x1f40, 16, 16, 6013},
+  {0x1f41, 16, 16, 6013},
+  {0x0, 0, 16, 6013},
+  {0xfa, 16, 16, 6029},
+  {0xf9, 16, 16, 6029},
+  {0x169, 16, 16, 6029},
+  {0xfb, 16, 16, 6029},
+  {0x16b, 16, 16, 6029},
+  {0x0, 3, 14, 6029},
+  {0x1ee4, 16, 16, 6040},
+  {0x16d, 16, 16, 6040},
+  {0x1ee7, 16, 16, 6040},
+  {0xfc, 16, 16, 6040},
+  {0x0, 0, 1, 6040},
+  {0x0, 3, 4, 6041},
+  {0x0, 0, 1, 6042},
+  {0x0, 9, 10, 6043},
+  {0x0, 9, 10, 6044},
+  {0x3062, 16, 16, 6045},
+  {0x172, 16, 16, 6045},
+  {0x0, 0, 1, 6045},
+  {0x0, 0, 1, 6046},
+  {0x0, 3, 4, 6047},
+  {0x0, 0, 1, 6048},
+  {0x0, 7, 8, 6049},
+  {0x1e65, 16, 16, 6050},
+  {0x0, 1, 13, 6050},
+  {0x161, 16, 16, 6062},
+  {0x0, 9, 13, 6062},
+  {0x2f9a1, 16, 16, 6066},
+  {0x0, 0, 1, 6066},
+  {0x0, 0, 1, 6067},
+  {0x0, 3, 4, 6068},
+  {0x0, 0, 1, 6069},
+  {0x0, 0, 13, 6070},
+  {0x1da, 16, 16, 6083},
+  {0x0, 0, 1, 6083},
+  {0x0, 0, 1, 6084},
+  {0x0, 3, 4, 6085},
+  {0x0, 0, 4, 6086},
+  {0x0, 1, 13, 6090},
+  {0x13a, 16, 16, 6102},
+  {0x16f, 16, 16, 6102},
+  {0x1e76, 16, 16, 6102},
+  {0x0, 0, 1, 6102},
+  {0x0, 0, 1, 6103},
+  {0x0, 3, 4, 6104},
+  {0x0, 3, 4, 6105},
+  {0x0, 8, 9, 6106},
+  {0x219b, 16, 16, 6107},
+  {0x171, 16, 16, 6107},
+  {0x215, 16, 16, 6107},
+  {0x0, 0, 1, 6107},
+  {0x0, 3, 4, 6108},
+  {0x0, 0, 1, 6109},
+  {0x0, 9, 10, 6110},
+  {0x0, 9, 10, 6111},
+  {0x3050, 16, 16, 6112},
+  {0x0, 10, 11, 6112},
+  {0x0, 7, 8, 6113},
+  {0x2f95e, 16, 16, 6114},
+  {0x0, 2, 3, 6114},
+  {0x2f9ba, 16, 16, 6115},
+  {0x0, 14, 15, 6115},
+  {0xfa30, 16, 16, 6116},
+  {0x0, 10, 11, 6116},
+  {0x2f861, 16, 16, 6117},
+  {0x13e, 16, 16, 6117},
+  {0x1dc, 16, 16, 6117},
+  {0x1d8, 16, 16, 6117},
+  {0x1d6, 16, 16, 6117},
+  {0x0, 2, 3, 6117},
+  {0x1fd7, 16, 16, 6118},
+  {0x0, 1, 2, 6118},
+  {0x0, 4, 5, 6119},
+  {0x2f927, 16, 16, 6120},
+  {0x15d, 16, 16, 6120},
+  {0x15b, 16, 16, 6120},
+  {0x1e61, 16, 16, 6120},
+  {0x0, 3, 5, 6120},
+  {0x1f49, 16, 16, 6122},
+  {0x0, 0, 1, 6122},
+  {0x0, 3, 4, 6123},
+  {0x0, 0, 1, 6124},
+  {0x0, 9, 10, 6125},
+  {0x0, 9, 10, 6126},
+  {0x30c5, 16, 16, 6127},
+  {0xf93e, 16, 16, 6127},
+  {0x0, 0, 14, 6127},
+  {0x0, 4, 5, 6141},
+  {0x2f9d9, 16, 16, 6142},
+  {0x0, 13, 14, 6142},
+  {0x2f8b4, 16, 16, 6143},
+  {0x1f48, 16, 16, 6143},
+  {0x0, 8, 9, 6143},
+  {0xf9e2, 16, 16, 6144},
+  {0x0, 3, 9, 6144},
+  {0x1eca, 16, 16, 6150},
+  {0x12e, 16, 16, 6150},
+  {0x0, 0, 9, 6150},
+  {0x1f7a, 16, 16, 6159},
+  {0x3cd, 16, 16, 6159},
+  {0x1fe1, 16, 16, 6159},
+  {0x0, 1, 2, 6159},
+  {0x1e35, 16, 16, 6160},
+  {0x1fe0, 16, 16, 6160},
+  {0x0, 0, 1, 6160},
+  {0x0, 3, 4, 6161},
+  {0x0, 0, 1, 6162},
+  {0x0, 9, 10, 6163},
+  {0x0, 9, 11, 6164},
+  {0x3074, 16, 16, 6166},
+  {0x3cb, 16, 16, 6166},
+  {0x0, 3, 4, 6166},
+  {0xf99d, 16, 16, 6167},
+  {0x0, 0, 1, 6167},
+  {0x0, 0, 1, 6168},
+  {0x0, 3, 4, 6169},
+  {0x0, 0, 1, 6170},
+  {0x0, 8, 9, 6171},
+  {0x4e7, 16, 16, 6172},
+  {0x1f3b, 16, 16, 6172},
+  {0x0, 0, 1, 6172},
+  {0x0, 0, 1, 6173},
+  {0x0, 3, 4, 6174},
+  {0x0, 4, 5, 6175},
+  {0x0, 5, 6, 6176},
+  {0x1f92, 16, 16, 6177},
+  {0x0, 2, 4, 6177},
+  {0xfa42, 16, 16, 6179},
+  {0x0, 1, 2, 6179},
+  {0x1e5f, 16, 16, 6180},
+  {0x0, 0, 1, 6180},
+  {0x0, 0, 1, 6181},
+  {0x0, 3, 4, 6182},
+  {0x0, 3, 4, 6183},
+  {0x0, 8, 9, 6184},
+  {0x22ed, 16, 16, 6185},
+  {0x0, 2, 6, 6185},
+  {0x1ff6, 16, 16, 6189},
+  {0x1ff3, 16, 16, 6189},
+  {0x0, 9, 11, 6189},
+  {0xf92a, 16, 16, 6191},
+  {0x0, 0, 1, 6191},
+  {0x0, 0, 1, 6192},
+  {0x0, 3, 4, 6193},
+  {0x0, 0, 5, 6194},
+  {0x0, 2, 6, 6199},
+  {0x1fa0, 16, 16, 6203},
+  {0x0, 4, 5, 6203},
+  {0xf9b7, 16, 16, 6204},
+  {0x1f66, 16, 16, 6204},
+  {0x3073, 16, 16, 6204},
+  {0x0, 2, 8, 6204},
+  {0x2f823, 16, 16, 6210},
+  {0x0, 12, 13, 6210},
+  {0x2f862, 16, 16, 6211},
+  {0x2f822, 16, 16, 6211},
+  {0x0, 2, 3, 6211},
+  {0xf9e5, 16, 16, 6212},
+  {0x2f903, 16, 16, 6212},
+  {0x0, 11, 12, 6212},
+  {0x2f957, 16, 16, 6213},
+  {0x0, 11, 12, 6213},
+  {0xf98a, 16, 16, 6214},
+  {0x0, 9, 10, 6214},
+  {0x2f9bb, 16, 16, 6215},
+  {0x0, 0, 1, 6215},
+  {0x0, 0, 1, 6216},
+  {0x0, 3, 4, 6217},
+  {0x0, 0, 1, 6218},
+  {0x0, 15, 16, 6219},
+  {0x476, 16, 16, 6220},
+  {0x0, 0, 1, 6220},
+  {0x0, 0, 1, 6221},
+  {0x0, 3, 4, 6222},
+  {0x0, 0, 1, 6223},
+  {0x0, 8, 9, 6224},
+  {0x4eb, 16, 16, 6225},
+  {0x0, 1, 6, 6225},
+  {0xfa5b, 16, 16, 6230},
+  {0xf934, 16, 16, 6230},
+  {0x0, 0, 10, 6230},
+  {0x0, 0, 1, 6240},
+  {0x0, 0, 1, 6241},
+  {0x0, 3, 4, 6242},
+  {0x0, 0, 1, 6243},
+  {0x0, 0, 2, 6244},
+  {0x1f14, 16, 16, 6246},
+  {0x1f12, 16, 16, 6246},
+  {0x0, 3, 14, 6246},
+  {0x1e0c, 16, 16, 6257},
+  {0x1e10, 16, 16, 6257},
+  {0x1ffb, 16, 16, 6257},
+  {0x1feb, 16, 16, 6257},
+  {0x1ff9, 16, 16, 6257},
+  {0x1fdb, 16, 16, 6257},
+  {0x0, 3, 4, 6257},
+  {0x2f992, 16, 16, 6258},
+  {0x0, 0, 1, 6258},
+  {0x0, 3, 4, 6259},
+  {0x0, 0, 1, 6260},
+  {0x0, 9, 10, 6261},
+  {0x0, 9, 10, 6262},
+  {0x30b6, 16, 16, 6263},
+  {0x0, 0, 1, 6263},
+  {0x0, 0, 1, 6264},
+  {0x0, 3, 4, 6265},
+  {0x0, 0, 4, 6266},
+  {0x0, 3, 14, 6270},
+  {0x1e36, 16, 16, 6281},
+  {0x13b, 16, 16, 6281},
+  {0x1e12, 16, 16, 6281},
+  {0x0, 1, 2, 6281},
+  {0x0, 14, 15, 6282},
+  {0x2f906, 16, 16, 6283},
+  {0x0, 0, 1, 6283},
+  {0x0, 0, 1, 6284},
+  {0x0, 3, 4, 6285},
+  {0x0, 0, 1, 6286},
+  {0x0, 8, 9, 6287},
+  {0x4ed, 16, 16, 6288},
+  {0x2f8dc, 16, 16, 6288},
+  {0x0, 6, 7, 6288},
+  {0x0, 3, 4, 6289},
+  {0x2f91d, 16, 16, 6290},
+  {0x1e3c, 16, 16, 6290},
+  {0x1fbb, 16, 16, 6290},
+  {0x1fee, 16, 16, 6290},
+  {0x0, 14, 15, 6290},
+  {0x2fa08, 16, 16, 6291},
+  {0x1fc9, 16, 16, 6291},
+  {0x0, 0, 1, 6291},
+  {0x0, 0, 1, 6292},
+  {0x0, 13, 14, 6293},
+  {0x0, 3, 4, 6294},
+  {0x0, 14, 15, 6295},
+  {0xd4b, 16, 16, 6296},
+  {0x0, 6, 7, 6296},
+  {0x2fa1b, 16, 16, 6297},
+  {0x0, 7, 8, 6297},
+  {0x2f896, 16, 16, 6298},
+  {0xf97a, 16, 16, 6298},
+  {0x0, 1, 13, 6298},
+  {0x17d, 16, 16, 6310},
+  {0x0, 4, 5, 6310},
+  {0xfa57, 16, 16, 6311},
+  {0x0, 8, 9, 6311},
+  {0xf972, 16, 16, 6312},
+  {0x0, 0, 1, 6312},
+  {0x0, 0, 1, 6313},
+  {0x0, 3, 4, 6314},
+  {0x0, 3, 4, 6315},
+  {0x0, 8, 9, 6316},
+  {0x226f, 16, 16, 6317},
+  {0x0, 0, 1, 6317},
+  {0x0, 0, 1, 6318},
+  {0x0, 3, 4, 6319},
+  {0x0, 0, 1, 6320},
+  {0x0, 0, 13, 6321},
+  {0x1d5, 16, 16, 6334},
+  {0x0, 6, 7, 6334},
+  {0x0, 7, 8, 6335},
+  {0x2f9c5, 16, 16, 6336},
+  {0x0, 0, 1, 6336},
+  {0x0, 0, 1, 6337},
+  {0x0, 3, 4, 6338},
+  {0x0, 4, 5, 6339},
+  {0x0, 5, 6, 6340},
+  {0x1fb7, 16, 16, 6341},
+  {0x1db, 16, 16, 6341},
+  {0x1d7, 16, 16, 6341},
+  {0x0, 3, 14, 6341},
+  {0x1e71, 16, 16, 6352},
+  {0x0, 0, 1, 6352},
+  {0x2f924, 16, 16, 6353},
+  {0x0, 0, 1, 6353},
+  {0x0, 0, 1, 6354},
+  {0x0, 3, 4, 6355},
+  {0x0, 3, 4, 6356},
+  {0x0, 8, 9, 6357},
+  {0x2247, 16, 16, 6358},
+  {0x0, 5, 6, 6358},
+  {0x0, 6, 7, 6359},
+  {0x2fa16, 16, 16, 6360},
+  {0x0, 0, 1, 6360},
+  {0x0, 0, 1, 6361},
+  {0x0, 3, 4, 6362},
+  {0x0, 4, 5, 6363},
+  {0x0, 5, 6, 6364},
+  {0x1f8a, 16, 16, 6365},
+  {0x0, 14, 15, 6365},
+  {0x2fa0d, 16, 16, 6366},
+  {0x0, 1, 2, 6366},
+  {0x2f8a0, 16, 16, 6367},
+  {0x2f8e4, 16, 16, 6367},
+  {0x0, 9, 10, 6367},
+  {0x2f8cd, 16, 16, 6368},
+  {0x0, 5, 10, 6368},
+  {0x2f8d7, 16, 16, 6373},
+  {0x1e90, 16, 16, 6373},
+  {0x179, 16, 16, 6373},
+  {0x2f981, 16, 16, 6373},
+  {0x17b, 16, 16, 6373},
+  {0x21b, 16, 16, 6373},
+  {0x163, 16, 16, 6373},
+  {0xfa4c, 16, 16, 6373},
+  {0x1e6d, 16, 16, 6373},
+  {0x37e, 16, 16, 6373},
+  {0x1d9, 16, 16, 6373},
+  {0x0, 0, 1, 6373},
+  {0x0, 3, 4, 6374},
+  {0x0, 0, 1, 6375},
+  {0x0, 9, 10, 6376},
+  {0x0, 9, 11, 6377},
+  {0x30d7, 16, 16, 6379},
+  {0x0, 0, 1, 6379},
+  {0x0, 3, 4, 6380},
+  {0x0, 0, 1, 6381},
+  {0x0, 9, 10, 6382},
+  {0x0, 9, 10, 6383},
+  {0x3060, 16, 16, 6384},
+  {0x0, 2, 6, 6384},
+  {0x1f91, 16, 16, 6388},
+  {0x1e16, 16, 16, 6388},
+  {0x1f27, 16, 16, 6388},
+  {0x0, 7, 8, 6388},
+  {0x2f89e, 16, 16, 6389},
+  {0x0, 9, 10, 6389},
+  {0x2f8c3, 16, 16, 6390},
+  {0x0, 1, 2, 6390},
+  {0x2f83a, 16, 16, 6391},
+  {0x0, 12, 13, 6391},
+  {0x2f880, 16, 16, 6392},
+  {0x2f989, 16, 16, 6392},
+  {0xd1, 16, 16, 6392},
+  {0x1f8, 16, 16, 6392},
+  {0x143, 16, 16, 6392},
+  {0x1e44, 16, 16, 6392},
+  {0x0, 11, 12, 6392},
+  {0x2f98e, 16, 16, 6393},
+  {0x0, 11, 12, 6393},
+  {0x2f933, 16, 16, 6394},
+  {0x0, 10, 11, 6394},
+  {0xf99b, 16, 16, 6395},
+  {0x0, 0, 1, 6395},
+  {0x1e75, 16, 16, 6396},
+  {0x0, 0, 1, 6396},
+  {0x0, 0, 1, 6397},
+  {0x0, 3, 4, 6398},
+  {0x0, 4, 5, 6399},
+  {0x0, 5, 6, 6400},
+  {0x1f8d, 16, 16, 6401},
+  {0x30d6, 16, 16, 6401},
+  {0x1f2b, 16, 16, 6401},
+  {0x0, 2, 3, 6401},
+  {0xf9ad, 16, 16, 6402},
+  {0xf95d, 16, 16, 6402},
+  {0x0, 0, 1, 6402},
+  {0x0, 0, 1, 6403},
+  {0x0, 3, 4, 6404},
+  {0x0, 0, 3, 6405},
+  {0x0, 3, 4, 6408},
+  {0x1e7c, 16, 16, 6409},
+  {0x0, 3, 4, 6409},
+  {0x0, 14, 15, 6410},
+  {0x2f977, 16, 16, 6411},
+  {0x0, 0, 1, 6411},
+  {0x0, 3, 4, 6412},
+  {0x0, 0, 1, 6413},
+  {0x0, 9, 10, 6414},
+  {0x0, 9, 10, 6415},
+  {0x305e, 16, 16, 6416},
+  {0x0, 0, 1, 6416},
+  {0x2f842, 16, 16, 6417},
+  {0x0, 3, 4, 6417},
+  {0x2f90a, 16, 16, 6418},
+  {0x0, 0, 9, 6418},
+  {0x38e, 16, 16, 6427},
+  {0x0, 0, 1, 6427},
+  {0xf9ee, 16, 16, 6428},
+  {0x0, 15, 16, 6428},
+  {0x2f80b, 16, 16, 6429},
+  {0x0, 10, 11, 6429},
+  {0xf919, 16, 16, 6430},
+  {0xf912, 16, 16, 6430},
+  {0x0, 13, 14, 6430},
+  {0x0, 10, 11, 6431},
+  {0x2f898, 16, 16, 6432},
+  {0x211, 16, 16, 6432},
+  {0x159, 16, 16, 6432},
+  {0x0, 12, 13, 6432},
+  {0xfa2b, 16, 16, 6433},
+  {0x0, 10, 11, 6433},
+  {0xf9bb, 16, 16, 6434},
+  {0x0, 0, 1, 6434},
+  {0x0, 0, 1, 6435},
+  {0x0, 3, 4, 6436},
+  {0x0, 4, 5, 6437},
+  {0x0, 5, 6, 6438},
+  {0x1f83, 16, 16, 6439},
+  {0x1ff8, 16, 16, 6439},
+  {0x0, 11, 12, 6439},
+  {0x2f9d4, 16, 16, 6440},
+  {0x0, 1, 12, 6440},
+  {0x216, 16, 16, 6451},
+  {0x0, 0, 1, 6451},
+  {0x0, 0, 1, 6452},
+  {0x0, 3, 4, 6453},
+  {0x0, 0, 1, 6454},
+  {0x0, 4, 5, 6455},
+  {0x1e0, 16, 16, 6456},
+  {0x0, 0, 16, 6456},
+  {0x0, 6, 7, 6472},
+  {0xfa37, 16, 16, 6473},
+  {0x0, 0, 1, 6473},
+  {0x0, 0, 1, 6474},
+  {0x0, 3, 4, 6475},
+  {0x0, 3, 4, 6476},
+  {0x0, 8, 9, 6477},
+  {0x22e3, 16, 16, 6478},
+  {0x0, 0, 2, 6478},
+  {0x1f6a, 16, 16, 6480},
+  {0x1f6c, 16, 16, 6480},
+  {0x137, 16, 16, 6480},
+  {0x0, 3, 5, 6480},
+  {0x1f51, 16, 16, 6482},
+  {0x1f50, 16, 16, 6482},
+  {0x0, 1, 2, 6482},
+  {0x0, 5, 6, 6483},
+  {0x2f9ec, 16, 16, 6484},
+  {0x0, 14, 15, 6484},
+  {0x2f8c2, 16, 16, 6485},
+  {0x0, 13, 14, 6485},
+  {0x2f99d, 16, 16, 6486},
+  {0x1af, 16, 16, 6486},
+  {0x0, 9, 10, 6486},
+  {0xf9c7, 16, 16, 6487},
+  {0x1e59, 16, 16, 6487},
+  {0x4d3, 16, 16, 6487},
+  {0x0, 0, 1, 6487},
+  {0x0, 0, 1, 6488},
+  {0x0, 3, 4, 6489},
+  {0x0, 0, 1, 6490},
+  {0x0, 7, 8, 6491},
+  {0x1e1f, 16, 16, 6492},
+  {0x0, 7, 8, 6492},
+  {0x2f9bf, 16, 16, 6493},
+  {0x0, 2, 5, 6493},
+  {0xf73, 16, 16, 6496},
+  {0xf75, 16, 16, 6496},
+  {0x0, 8, 9, 6496},
+  {0x2f83f, 16, 16, 6497},
+  {0x0, 3, 5, 6497},
+  {0x1f30, 16, 16, 6499},
+  {0x1f31, 16, 16, 6499},
+  {0x0, 15, 16, 6499},
+  {0xf913, 16, 16, 6500},
+  {0x0, 0, 11, 6500},
+  {0x1e87, 16, 16, 6511},
+  {0x0, 0, 2, 6511},
+  {0x1fcd, 16, 16, 6513},
+  {0x1fce, 16, 16, 6513},
+  {0x175, 16, 16, 6513},
+  {0x1e83, 16, 16, 6513},
+  {0x1e81, 16, 16, 6513},
+  {0x0, 12, 13, 6513},
+  {0x2f8b8, 16, 16, 6514},
+  {0x0, 5, 6, 6514},
+  {0x1ffc, 16, 16, 6515},
+  {0xfa45, 16, 16, 6515},
+  {0x1e85, 16, 16, 6515},
+  {0x0, 3, 9, 6515},
+  {0x1ecc, 16, 16, 6521},
+  {0x0, 0, 1, 6521},
+  {0x0, 0, 1, 6522},
+  {0x0, 11, 12, 6523},
+  {0x0, 11, 12, 6524},
+  {0x0, 14, 15, 6525},
+  {0xbcb, 16, 16, 6526},
+  {0x1ea, 16, 16, 6526},
+  {0x0, 0, 1, 6526},
+  {0x0, 0, 1, 6527},
+  {0x0, 3, 4, 6528},
+  {0x0, 3, 4, 6529},
+  {0x0, 8, 9, 6530},
+  {0x22ac, 16, 16, 6531},
+  {0x0, 1, 2, 6531},
+  {0x0, 10, 11, 6532},
+  {0x2f9f7, 16, 16, 6533},
+  {0x0, 12, 13, 6533},
+  {0xf956, 16, 16, 6534},
+  {0x0, 0, 1, 6534},
+  {0x0, 0, 1, 6535},
+  {0x0, 3, 4, 6536},
+  {0x0, 0, 1, 6537},
+  {0x0, 8, 9, 6538},
+  {0x4f8, 16, 16, 6539},
+  {0x0, 12, 16, 6539},
+  {0xf9e9, 16, 16, 6543},
+  {0xf97e, 16, 16, 6543},
+  {0x0, 14, 15, 6543},
+  {0x2f8af, 16, 16, 6544},
+  {0x21f, 16, 16, 6544},
+  {0x1e98, 16, 16, 6544},
+  {0x0, 1, 2, 6544},
+  {0x1e3a, 16, 16, 6545},
+  {0x0, 7, 8, 6545},
+  {0x9cc, 16, 16, 6546},
+  {0x0, 3, 15, 6546},
+  {0x1e2a, 16, 16, 6558},
+  {0x0, 5, 16, 6558},
+  {0x2fa1a, 16, 16, 6569},
+  {0x2f81a, 16, 16, 6569},
+  {0x0, 7, 12, 6569},
+  {0x2f929, 16, 16, 6574},
+  {0x0, 2, 16, 6574},
+  {0xf94f, 16, 16, 6588},
+  {0x0, 14, 15, 6588},
+  {0xf920, 16, 16, 6589},
+  {0x0, 10, 11, 6589},
+  {0x0, 14, 15, 6590},
+  {0x2f9cb, 16, 16, 6591},
+  {0xf9a0, 16, 16, 6591},
+  {0x1e28, 16, 16, 6591},
+  {0x0, 1, 2, 6591},
+  {0x2f8da, 16, 16, 6592},
+  {0x1e24, 16, 16, 6592},
+  {0x2fa19, 16, 16, 6592},
+  {0xf9db, 16, 16, 6592},
+  {0x0, 0, 1, 6592},
+  {0x0, 0, 1, 6593},
+  {0x0, 3, 4, 6594},
+  {0x0, 0, 3, 6595},
+  {0x0, 7, 8, 6598},
+  {0x122, 16, 16, 6599},
+  {0x0, 0, 2, 6599},
+  {0x1f2a, 16, 16, 6601},
+  {0x1f2c, 16, 16, 6601},
+  {0x0, 0, 1, 6601},
+  {0x0, 0, 1, 6602},
+  {0x0, 3, 4, 6603},
+  {0x0, 4, 5, 6604},
+  {0x0, 5, 6, 6605},
+  {0x1f93, 16, 16, 6606},
+  {0x0, 14, 15, 6606},
+  {0xbca, 16, 16, 6607},
+  {0x0, 6, 7, 6607},
+  {0x2f912, 16, 16, 6608},
+  {0x0, 5, 6, 6608},
+  {0x2f9f6, 16, 16, 6609},
+  {0x0, 3, 4, 6609},
+  {0x2f8dd, 16, 16, 6610},
+  {0xf96a, 16, 16, 6610},
+  {0x0, 14, 15, 6610},
+  {0x2f90f, 16, 16, 6611},
+  {0x0, 9, 10, 6611},
+  {0x374, 16, 16, 6612},
+  {0x0, 6, 11, 6612},
+  {0xf998, 16, 16, 6617},
+  {0x0, 4, 5, 6617},
+  {0xfa3d, 16, 16, 6618},
+  {0x0, 2, 6, 6618},
+  {0x1f26, 16, 16, 6622},
+  {0x0, 7, 15, 6622},
+  {0x2f8c4, 16, 16, 6630},
+  {0x0, 0, 1, 6630},
+  {0x2f922, 16, 16, 6631},
+  {0x0, 1, 2, 6631},
+  {0xf96d, 16, 16, 6632},
+  {0x0, 1, 2, 6632},
+  {0x1e6f, 16, 16, 6633},
+  {0x0, 0, 1, 6633},
+  {0x0, 0, 1, 6634},
+  {0x0, 3, 4, 6635},
+  {0x0, 4, 5, 6636},
+  {0x0, 5, 6, 6637},
+  {0x1fa4, 16, 16, 6638},
+  {0x0, 0, 1, 6638},
+  {0x0, 0, 1, 6639},
+  {0x0, 3, 4, 6640},
+  {0x0, 0, 4, 6641},
+  {0x0, 1, 13, 6645},
+  {0x17e, 16, 16, 6657},
+  {0x1f90, 16, 16, 6657},
+  {0x0, 0, 2, 6657},
+  {0x1f5b, 16, 16, 6659},
+  {0x1f5d, 16, 16, 6659},
+  {0x0, 5, 6, 6659},
+  {0xfa04, 16, 16, 6660},
+  {0x1f6e, 16, 16, 6660},
+  {0x0, 0, 1, 6660},
+  {0x0, 0, 1, 6661},
+  {0x0, 3, 4, 6662},
+  {0x0, 0, 3, 6663},
+  {0x0, 1, 13, 6666},
+  {0x11f, 16, 16, 6678},
+  {0x121, 16, 16, 6678},
+  {0x1e21, 16, 16, 6678},
+  {0x11d, 16, 16, 6678},
+  {0x1f5, 16, 16, 6678},
+  {0x0, 3, 4, 6678},
+  {0x2f8bc, 16, 16, 6679},
+  {0x17c, 16, 16, 6679},
+  {0x17a, 16, 16, 6679},
+  {0x1e91, 16, 16, 6679},
+  {0x0, 1, 2, 6679},
+  {0x2f8b5, 16, 16, 6680},
+  {0xf9d7, 16, 16, 6680},
+  {0x2f8c6, 16, 16, 6680},
+  {0x1e7, 16, 16, 6680},
+  {0x0, 4, 5, 6680},
+  {0xf943, 16, 16, 6681},
+  {0x0, 0, 1, 6681},
+  {0x0, 0, 1, 6682},
+  {0x0, 3, 4, 6683},
+  {0x0, 0, 1, 6684},
+  {0x0, 0, 10, 6685},
+  {0x1ed7, 16, 16, 6695},
+  {0x0, 0, 1, 6695},
+  {0x0, 0, 1, 6696},
+  {0x0, 3, 4, 6697},
+  {0x0, 4, 5, 6698},
+  {0x0, 5, 6, 6699},
+  {0x1f8f, 16, 16, 6700},
+  {0x1ed1, 16, 16, 6700},
+  {0x1ed3, 16, 16, 6700},
+  {0x0, 2, 14, 6700},
+  {0xf95e, 16, 16, 6712},
+  {0x2f801, 16, 16, 6712},
+  {0x1ed5, 16, 16, 6712},
+  {0xf905, 16, 16, 6712},
+  {0x0, 0, 2, 6712},
+  {0x1f6d, 16, 16, 6714},
+  {0x1f6b, 16, 16, 6714},
+  {0x0, 10, 11, 6714},
+  {0x2f808, 16, 16, 6715},
+  {0x0, 15, 16, 6715},
+  {0x0, 0, 1, 6716},
+  {0x0, 0, 1, 6717},
+  {0x0, 12, 13, 6718},
+  {0x0, 13, 14, 6719},
+  {0x0, 5, 6, 6720},
+  {0xcc0, 16, 16, 6721},
+  {0x0, 0, 16, 6721},
+  {0x214, 16, 16, 6737},
+  {0x0, 11, 12, 6737},
+  {0xf953, 16, 16, 6738},
+  {0x1d3, 16, 16, 6738},
+  {0x170, 16, 16, 6738},
+  {0x16e, 16, 16, 6738},
+  {0x0, 3, 14, 6738},
+  {0x1e77, 16, 16, 6749},
+  {0x0, 3, 14, 6749},
+  {0x13c, 16, 16, 6760},
+  {0x1e37, 16, 16, 6760},
+  {0x0, 0, 1, 6760},
+  {0x0, 0, 1, 6761},
+  {0x0, 3, 4, 6762},
+  {0x0, 1, 2, 6763},
+  {0x0, 4, 5, 6764},
+  {0x1fec, 16, 16, 6765},
+  {0x0, 14, 15, 6765},
+  {0x0, 4, 5, 6766},
+  {0x2f859, 16, 16, 6767},
+  {0x2f800, 16, 16, 6767},
+  {0x1e3d, 16, 16, 6767},
+  {0x0, 0, 1, 6767},
+  {0x0, 3, 4, 6768},
+  {0x0, 0, 1, 6769},
+  {0x0, 9, 10, 6770},
+  {0x0, 9, 10, 6771},
+  {0x304e, 16, 16, 6772},
+  {0x0, 11, 15, 6772},
+  {0x2f87e, 16, 16, 6776},
+  {0x2f8cb, 16, 16, 6776},
+  {0x1e84, 16, 16, 6776},
+  {0x0, 0, 1, 6776},
+  {0x0, 0, 1, 6777},
+  {0x0, 3, 4, 6778},
+  {0x0, 0, 1, 6779},
+  {0x0, 1, 2, 6780},
+  {0x403, 16, 16, 6781},
+  {0x173, 16, 16, 6781},
+  {0x1ee6, 16, 16, 6781},
+  {0xdc, 16, 16, 6781},
+  {0x1ee5, 16, 16, 6781},
+  {0x16c, 16, 16, 6781},
+  {0x16a, 16, 16, 6781},
+  {0x168, 16, 16, 6781},
+  {0xdb, 16, 16, 6781},
+  {0x0, 8, 11, 6781},
+  {0x0, 0, 1, 6784},
+  {0x0, 0, 1, 6785},
+  {0x0, 6, 7, 6786},
+  {0x0, 5, 6, 6787},
+  {0x0, 4, 5, 6788},
+  {0x626, 16, 16, 6789},
+  {0x1e73, 16, 16, 6789},
+  {0x0, 5, 7, 6789},
+  {0xcc7, 16, 16, 6791},
+  {0x0, 0, 1, 6791},
+  {0x0, 0, 1, 6792},
+  {0x0, 3, 4, 6793},
+  {0x0, 0, 3, 6794},
+  {0x0, 0, 11, 6797},
+  {0x233, 16, 16, 6808},
+  {0x1e8f, 16, 16, 6808},
+  {0xcc8, 16, 16, 6808},
+  {0xfd, 16, 16, 6808},
+  {0x1ef3, 16, 16, 6808},
+  {0x1ef9, 16, 16, 6808},
+  {0x177, 16, 16, 6808},
+  {0x0, 12, 13, 6808},
+  {0x2f812, 16, 16, 6809},
+  {0x1ef7, 16, 16, 6809},
+  {0xff, 16, 16, 6809},
+  {0x1e80, 16, 16, 6809},
+  {0x0, 14, 15, 6809},
+  {0x2f83c, 16, 16, 6810},
+  {0x0, 2, 3, 6810},
+  {0x0, 0, 1, 6811},
+  {0x0, 0, 1, 6812},
+  {0x0, 11, 12, 6813},
+  {0x0, 13, 14, 6814},
+  {0x0, 7, 8, 6815},
+  {0xb94, 16, 16, 6816},
+  {0x0, 10, 11, 6816},
+  {0x0, 11, 12, 6817},
+  {0x2f961, 16, 16, 6818},
+  {0x0, 1, 2, 6818},
+  {0x213, 16, 16, 6819},
+  {0x0, 1, 12, 6819},
+  {0x1a0, 16, 16, 6830},
+  {0x0, 0, 9, 6830},
+  {0x3ca, 16, 16, 6839},
+  {0x0, 11, 12, 6839},
+  {0xf9f5, 16, 16, 6840},
+  {0x3af, 16, 16, 6840},
+  {0x1f76, 16, 16, 6840},
+  {0x1fd1, 16, 16, 6840},
+  {0x1fd0, 16, 16, 6840},
+  {0x1e99, 16, 16, 6840},
+  {0x0, 1, 2, 6840},
+  {0xf9ca, 16, 16, 6841},
+  {0x0, 1, 2, 6841},
+  {0x2f802, 16, 16, 6842},
+  {0x0, 0, 1, 6842},
+  {0x0, 0, 1, 6843},
+  {0x0, 6, 7, 6844},
+  {0x0, 5, 6, 6845},
+  {0x0, 4, 5, 6846},
+  {0x624, 16, 16, 6847},
+  {0x20e, 16, 16, 6847},
+  {0x0, 0, 1, 6847},
+  {0x0, 0, 1, 6848},
+  {0x0, 3, 4, 6849},
+  {0x0, 4, 5, 6850},
+  {0x0, 5, 6, 6851},
+  {0x1fae, 16, 16, 6852},
+  {0x0, 4, 5, 6852},
+  {0x2f8bd, 16, 16, 6853},
+  {0x0, 9, 10, 6853},
+  {0x2f949, 16, 16, 6854},
+  {0x0, 4, 5, 6854},
+  {0xf9a8, 16, 16, 6855},
+  {0x0, 3, 9, 6855},
+  {0x1e01, 16, 16, 6861},
+  {0x1ea1, 16, 16, 6861},
+  {0x1ef8, 16, 16, 6861},
+  {0x0, 0, 16, 6861},
+  {0x101, 16, 16, 6877},
+  {0x105, 16, 16, 6877},
+  {0x1f32, 16, 16, 6877},
+  {0x0, 0, 1, 6877},
+  {0x0, 3, 4, 6878},
+  {0x0, 0, 1, 6879},
+  {0x0, 9, 10, 6880},
+  {0x0, 9, 10, 6881},
+  {0x3069, 16, 16, 6882},
+  {0x0, 1, 13, 6882},
+  {0x139, 16, 16, 6894},
+  {0x0, 12, 13, 6894},
+  {0x2f9db, 16, 16, 6895},
+  {0x0, 9, 10, 6895},
+  {0xf96e, 16, 16, 6896},
+  {0x0, 3, 4, 6896},
+  {0x0, 0, 1, 6897},
+  {0x2fa09, 16, 16, 6898},
+  {0x0, 13, 14, 6898},
+  {0xf99e, 16, 16, 6899},
+  {0x0, 2, 3, 6899},
+  {0x2f85e, 16, 16, 6900},
+  {0x0, 13, 14, 6900},
+  {0xf91f, 16, 16, 6901},
+  {0x0, 13, 14, 6901},
+  {0x2f91a, 16, 16, 6902},
+  {0x13d, 16, 16, 6902},
+  {0x0, 0, 1, 6902},
+  {0x0, 3, 4, 6903},
+  {0x0, 0, 1, 6904},
+  {0x0, 9, 10, 6905},
+  {0x0, 9, 10, 6906},
+  {0x30f8, 16, 16, 6907},
+  {0x0, 5, 6, 6907},
+  {0x2f81d, 16, 16, 6908},
+  {0x2f945, 16, 16, 6908},
+  {0x0, 0, 1, 6908},
+  {0x0, 3, 4, 6909},
+  {0x0, 0, 1, 6910},
+  {0x0, 9, 10, 6911},
+  {0x0, 9, 10, 6912},
+  {0x30fa, 16, 16, 6913},
+  {0x0, 7, 12, 6913},
+  {0xf929, 16, 16, 6918},
+  {0x0, 14, 15, 6918},
+  {0xf917, 16, 16, 6919},
+  {0x0, 8, 12, 6919},
+  {0xfa07, 16, 16, 6923},
+  {0x0, 2, 6, 6923},
+  {0x1f0e, 16, 16, 6927},
+  {0x0, 0, 1, 6927},
+  {0x0, 0, 1, 6928},
+  {0x0, 3, 4, 6929},
+  {0x0, 0, 1, 6930},
+  {0x0, 1, 2, 6931},
+  {0x45c, 16, 16, 6932},
+  {0x1f88, 16, 16, 6932},
+  {0x0, 0, 1, 6932},
+  {0x0, 0, 1, 6933},
+  {0x0, 3, 4, 6934},
+  {0x0, 0, 1, 6935},
+  {0x0, 0, 2, 6936},
+  {0x1f4d, 16, 16, 6938},
+  {0x1f4b, 16, 16, 6938},
+  {0x0, 0, 1, 6938},
+  {0x0, 0, 1, 6939},
+  {0x0, 3, 4, 6940},
+  {0x0, 3, 4, 6941},
+  {0x0, 8, 9, 6942},
+  {0x22eb, 16, 16, 6943},
+  {0x0, 0, 1, 6943},
+  {0x0, 0, 1, 6944},
+  {0x0, 3, 4, 6945},
+  {0x0, 3, 4, 6946},
+  {0x0, 8, 9, 6947},
+  {0x226e, 16, 16, 6948},
+  {0x0, 0, 1, 6948},
+  {0xf9cf, 16, 16, 6949},
+  {0x0, 15, 16, 6949},
+  {0x2f8f4, 16, 16, 6950},
+  {0x0, 3, 5, 6950},
+  {0x1f11, 16, 16, 6952},
+  {0x1f10, 16, 16, 6952},
+  {0x0, 0, 1, 6952},
+  {0x0, 0, 1, 6953},
+  {0x0, 3, 4, 6954},
+  {0x0, 1, 2, 6955},
+  {0x0, 3, 5, 6956},
+  {0x1fe4, 16, 16, 6958},
+  {0x2f9df, 16, 16, 6958},
+  {0x1fe5, 16, 16, 6958},
+  {0x0, 0, 1, 6958},
+  {0x0, 3, 4, 6959},
+  {0x0, 0, 1, 6960},
+  {0x0, 9, 10, 6961},
+  {0x0, 9, 10, 6962},
+  {0x3067, 16, 16, 6963},
+  {0x1f4c, 16, 16, 6963},
+  {0x0, 6, 7, 6963},
+  {0x0, 10, 11, 6964},
+  {0xf987, 16, 16, 6965},
+  {0x2f87f, 16, 16, 6965},
+  {0x2f8d9, 16, 16, 6965},
+  {0x0, 0, 1, 6965},
+  {0xf990, 16, 16, 6966},
+  {0x0, 0, 1, 6966},
+  {0x2f879, 16, 16, 6967},
+  {0x1f73, 16, 16, 6967},
+  {0x0, 7, 8, 6967},
+  {0x2f9f0, 16, 16, 6968},
+  {0x1f77, 16, 16, 6968},
+  {0x1f71, 0, 1, 6968},
+  {0x0, 3, 4, 6969},
+  {0x0, 1, 2, 6970},
+  {0x2f892, 16, 16, 6971},
+  {0x0, 1, 2, 6971},
+  {0x1e95, 16, 16, 6972},
+  {0x0, 0, 1, 6972},
+  {0x0, 0, 1, 6973},
+  {0x0, 3, 4, 6974},
+  {0x0, 4, 5, 6975},
+  {0x0, 5, 6, 6976},
+  {0x1fa5, 16, 16, 6977},
+  {0x0, 0, 1, 6977},
+  {0x0, 3, 4, 6978},
+  {0x0, 4, 5, 6979},
+  {0x0, 5, 6, 6980},
+  {0x1fb4, 16, 16, 6981},
+  {0xf925, 16, 16, 6981},
+  {0xda, 16, 16, 6981},
+  {0x0, 6, 10, 6981},
+  {0xf9cc, 16, 16, 6985},
+  {0xf9e4, 16, 16, 6985},
+  {0x0, 3, 14, 6985},
+  {0x145, 16, 16, 6996},
+  {0x1e46, 16, 16, 6996},
+  {0x0, 3, 4, 6996},
+  {0x0, 5, 6, 6997},
+  {0x2f926, 16, 16, 6998},
+  {0x0, 2, 3, 6998},
+  {0x1fc1, 16, 16, 6999},
+  {0x0, 11, 12, 6999},
+  {0x2f9ff, 16, 16, 7000},
+  {0x0, 5, 6, 7000},
+  {0x2f955, 16, 16, 7001},
+  {0x0, 0, 1, 7001},
+  {0x0, 0, 1, 7002},
+  {0x0, 3, 4, 7003},
+  {0x0, 0, 1, 7004},
+  {0x0, 7, 8, 7005},
+  {0x1e66, 16, 16, 7006},
+  {0x0, 0, 1, 7006},
+  {0x0, 0, 1, 7007},
+  {0x0, 3, 4, 7008},
+  {0x0, 0, 1, 7009},
+  {0x0, 8, 9, 7010},
+  {0x4e6, 16, 16, 7011},
+  {0x0, 1, 2, 7011},
+  {0x1e3b, 16, 16, 7012},
+  {0x0, 7, 8, 7012},
+  {0x2f99e, 16, 16, 7013},
+  {0x1e4a, 16, 16, 7013},
+  {0xd9, 16, 16, 7013},
+  {0x0, 3, 4, 7013},
+  {0x1e7e, 16, 16, 7014},
+  {0x0, 0, 1, 7014},
+  {0x0, 0, 1, 7015},
+  {0x0, 3, 4, 7016},
+  {0x0, 0, 1, 7017},
+  {0x0, 1, 9, 7018},
+  {0x22d, 16, 16, 7026},
+  {0x0, 0, 1, 7026},
+  {0x0, 3, 4, 7027},
+  {0x0, 0, 1, 7028},
+  {0x0, 9, 10, 7029},
+  {0x0, 9, 10, 7030},
+  {0x30be, 16, 16, 7031},
+  {0x1e4d, 16, 16, 7031},
+  {0x1e4f, 16, 16, 7031},
+  {0x0, 0, 1, 7031},
+  {0x0, 0, 1, 7032},
+  {0x0, 3, 4, 7033},
+  {0x0, 3, 4, 7034},
+  {0x0, 8, 9, 7035},
+  {0x220c, 16, 16, 7036},
+  {0x0, 4, 5, 7036},
+  {0x2f84f, 16, 16, 7037},
+  {0x0, 3, 12, 7037},
+  {0xf931, 16, 16, 7046},
+  {0x0, 3, 4, 7046},
+  {0x2f849, 16, 16, 7047},
+  {0x0, 0, 1, 7047},
+  {0x0, 0, 1, 7048},
+  {0x0, 3, 4, 7049},
+  {0x0, 0, 1, 7050},
+  {0x0, 0, 2, 7051},
+  {0x1f1b, 16, 16, 7053},
+  {0x1f1d, 16, 16, 7053},
+  {0x0, 0, 1, 7053},
+  {0x0, 0, 1, 7054},
+  {0x0, 3, 4, 7055},
+  {0x0, 0, 1, 7056},
+  {0x0, 4, 5, 7057},
+  {0x22b, 16, 16, 7058},
+  {0x0, 8, 9, 7058},
+  {0xfa38, 16, 16, 7059},
+  {0x0, 7, 8, 7059},
+  {0xc7, 16, 16, 7060},
+  {0x0, 14, 15, 7060},
+  {0x2f936, 16, 16, 7061},
+  {0x0, 1, 9, 7061},
+  {0xf948, 16, 16, 7069},
+  {0x2f9d5, 16, 16, 7069},
+  {0x0, 12, 13, 7069},
+  {0x2f9a3, 16, 16, 7070},
+  {0xf903, 16, 16, 7070},
+  {0x2f8ed, 16, 16, 7070},
+  {0x0, 8, 9, 7070},
+  {0xf9b8, 16, 16, 7071},
+  {0x0, 11, 12, 7071},
+  {0x2f9da, 16, 16, 7072},
+  {0x0, 0, 11, 7072},
+  {0x2f9cf, 16, 16, 7083},
+  {0x0, 0, 1, 7083},
+  {0x0, 0, 1, 7084},
+  {0x0, 3, 4, 7085},
+  {0x0, 3, 4, 7086},
+  {0x0, 8, 9, 7087},
+  {0x2249, 16, 16, 7088},
+  {0x0, 6, 8, 7088},
+  {0x2f84b, 16, 16, 7090},
+  {0x2f84d, 16, 16, 7090},
+  {0x0, 6, 7, 7090},
+  {0x2f821, 16, 16, 7091},
+  {0x1ece, 16, 16, 7091},
+  {0xd6, 16, 16, 7091},
+  {0x22e, 16, 16, 7091},
+  {0x14e, 16, 16, 7091},
+  {0x14c, 16, 16, 7091},
+  {0x0, 13, 14, 7091},
+  {0x0, 10, 11, 7092},
+  {0x2f97b, 16, 16, 7093},
+  {0xd4, 16, 16, 7093},
+  {0xd3, 16, 16, 7093},
+  {0xd2, 16, 16, 7093},
+  {0x1eb3, 16, 16, 7093},
+  {0xfa40, 16, 16, 7093},
+  {0x1eb5, 16, 16, 7093},
+  {0x0, 13, 14, 7093},
+  {0x2f854, 16, 16, 7094},
+  {0x1eb1, 16, 16, 7094},
+  {0x0, 14, 15, 7094},
+  {0x2f890, 16, 16, 7095},
+  {0x0, 8, 9, 7095},
+  {0xfa67, 16, 16, 7096},
+  {0x0, 10, 16, 7096},
+  {0xdda, 16, 16, 7102},
+  {0x0, 8, 9, 7102},
+  {0xf9b4, 16, 16, 7103},
+  {0xddc, 16, 16, 7103},
+  {0xf9a1, 16, 16, 7103},
+  {0x0, 0, 1, 7103},
+  {0x0, 0, 1, 7104},
+  {0x0, 3, 4, 7105},
+  {0x0, 4, 5, 7106},
+  {0x0, 5, 6, 7107},
+  {0x1f8b, 16, 16, 7108},
+  {0x0, 3, 4, 7108},
+  {0x2f9f5, 16, 16, 7109},
+  {0x0, 14, 15, 7109},
+  {0x2f9b9, 16, 16, 7110},
+  {0x20c, 16, 16, 7110},
+  {0x0, 0, 1, 7110},
+  {0x0, 0, 1, 7111},
+  {0x0, 3, 4, 7112},
+  {0x0, 3, 4, 7113},
+  {0x0, 8, 9, 7114},
+  {0x2284, 16, 16, 7115},
+  {0x1d1, 16, 16, 7115},
+  {0x150, 16, 16, 7115},
+  {0x0, 7, 8, 7115},
+  {0xfa5f, 16, 16, 7116},
+  {0x0, 1, 13, 7116},
+  {0x1e6, 16, 16, 7128},
+  {0x0, 6, 7, 7128},
+  {0x2f9fd, 16, 16, 7129},
+  {0x0, 0, 1, 7129},
+  {0x0, 5, 6, 7130},
+  {0x2fa12, 16, 16, 7131},
+  {0x0, 8, 10, 7131},
+  {0x2fa04, 16, 16, 7133},
+  {0xfa2c, 16, 16, 7133},
+  {0x0, 15, 16, 7133},
+  {0xf940, 16, 16, 7134},
+  {0x0, 1, 2, 7134},
+  {0xfa4b, 16, 16, 7135},
+  {0x30d1, 16, 16, 7135},
+  {0x0, 2, 11, 7135},
+  {0x2f9f4, 16, 16, 7144},
+  {0x0, 15, 16, 7144},
+  {0xf94e, 16, 16, 7145},
+  {0x0, 0, 1, 7145},
+  {0x2f8d4, 16, 16, 7146},
+  {0x1f00, 16, 16, 7146},
+  {0x1f4, 16, 16, 7146},
+  {0x11c, 16, 16, 7146},
+  {0x1e20, 16, 16, 7146},
+  {0x11e, 16, 16, 7146},
+  {0x120, 16, 16, 7146},
+  {0x0, 3, 4, 7146},
+  {0x2f9f3, 16, 16, 7147},
+  {0x0, 9, 10, 7147},
+  {0xf9fb, 16, 16, 7148},
+  {0x1fef, 16, 16, 7148},
+  {0xf9ab, 16, 16, 7148},
+  {0x0, 3, 4, 7148},
+  {0xf94c, 16, 16, 7149},
+  {0x0, 0, 1, 7149},
+  {0x0, 0, 1, 7150},
+  {0x0, 3, 4, 7151},
+  {0x0, 4, 5, 7152},
+  {0x0, 5, 6, 7153},
+  {0x1f96, 16, 16, 7154},
+  {0x0, 0, 1, 7154},
+  {0x2f96a, 16, 16, 7155},
+  {0x1f72, 16, 16, 7155},
+  {0x0, 7, 12, 7155},
+  {0x2f90c, 16, 16, 7160},
+  {0x0, 0, 11, 7160},
+  {0x2f9d1, 16, 16, 7171},
+  {0x0, 0, 1, 7171},
+  {0x0, 0, 1, 7172},
+  {0x0, 3, 4, 7173},
+  {0x0, 0, 1, 7174},
+  {0x0, 1, 2, 7175},
+  {0x40c, 16, 16, 7176},
+  {0x0, 2, 12, 7176},
+  {0x2f89a, 16, 16, 7186},
+  {0x0, 7, 8, 7186},
+  {0x123, 16, 16, 7187},
+  {0x0, 5, 7, 7187},
+  {0xf974, 16, 16, 7189},
+  {0x2f996, 16, 16, 7189},
+  {0x0, 3, 4, 7189},
+  {0x1e93, 16, 16, 7190},
+  {0x0, 2, 3, 7190},
+  {0x1fe7, 16, 16, 7191},
+  {0x0, 2, 3, 7191},
+  {0x2f9fc, 16, 16, 7192},
+  {0x2f90b, 16, 16, 7192},
+  {0xf95a, 16, 16, 7192},
+  {0x0, 3, 5, 7192},
+  {0xfa02, 16, 16, 7194},
+  {0x2f8b6, 16, 16, 7194},
+  {0x0, 1, 2, 7194},
+  {0x1e48, 16, 16, 7195},
+  {0x4e4, 16, 16, 7195},
+  {0x4e2, 16, 16, 7195},
+  {0x0, 0, 1, 7195},
+  {0x0, 0, 1, 7196},
+  {0x0, 3, 4, 7197},
+  {0x0, 3, 4, 7198},
+  {0x0, 8, 9, 7199},
+  {0x2278, 16, 16, 7200},
+  {0x419, 16, 16, 7200},
+  {0x0, 1, 2, 7200},
+  {0x2f9c0, 16, 16, 7201},
+  {0x2f899, 16, 16, 7201},
+  {0x1e72, 16, 16, 7201},
+  {0x0, 4, 5, 7201},
+  {0xf98e, 16, 16, 7202},
+  {0x0, 5, 6, 7202},
+  {0x2f92b, 16, 16, 7203},
+  {0x0, 0, 1, 7203},
+  {0x2f9fa, 16, 16, 7204},
+  {0x0, 3, 14, 7204},
+  {0x1e0d, 16, 16, 7215},
+  {0x0, 6, 7, 7215},
+  {0x2f9f2, 16, 16, 7216},
+  {0x1e11, 16, 16, 7216},
+  {0x0, 14, 15, 7216},
+  {0x2f851, 16, 16, 7217},
+  {0x0, 6, 7, 7217},
+  {0x2f9f9, 16, 16, 7218},
+  {0x0, 2, 3, 7218},
+  {0xf9f9, 16, 16, 7219},
+  {0x0, 14, 15, 7219},
+  {0xf9a5, 16, 16, 7220},
+  {0x10f, 16, 16, 7220},
+  {0x0, 2, 6, 7220},
+  {0x1f0f, 16, 16, 7224},
+  {0x1f89, 16, 16, 7224},
+  {0x0, 15, 16, 7224},
+  {0x0, 0, 1, 7225},
+  {0x0, 0, 1, 7226},
+  {0x0, 3, 4, 7227},
+  {0x0, 0, 1, 7228},
+  {0x0, 7, 8, 7229},
+  {0x1e9b, 16, 16, 7230},
+  {0x1e13, 16, 16, 7230},
+  {0x0, 0, 3, 7230},
+  {0x2f84a, 16, 16, 7233},
+  {0xfa0d, 16, 16, 7233},
+  {0x0, 1, 2, 7233},
+  {0x2fa14, 16, 16, 7234},
+  {0x0, 12, 13, 7234},
+  {0x2f9ad, 16, 16, 7235},
+  {0x0, 10, 12, 7235},
+  {0xf9ff, 16, 16, 7237},
+  {0x2f820, 16, 16, 7237},
+  {0x0, 1, 2, 7237},
+  {0x2f84e, 16, 16, 7238},
+  {0x1fe8, 16, 16, 7238},
+  {0x1e58, 16, 16, 7238},
+  {0x1fe9, 16, 16, 7238},
+  {0x1fea, 16, 16, 7238},
+  {0x0, 13, 14, 7238},
+  {0x2f8f7, 16, 16, 7239},
+  {0x0, 0, 1, 7239},
+  {0x0, 0, 1, 7240},
+  {0x0, 3, 4, 7241},
+  {0x0, 4, 5, 7242},
+  {0x0, 5, 6, 7243},
+  {0x1f97, 16, 16, 7244},
+  {0x3ab, 16, 16, 7244},
+  {0x0, 3, 4, 7244},
+  {0xf9f1, 16, 16, 7245},
+  {0x210, 16, 16, 7245},
+  {0x2f9a2, 16, 16, 7245},
+  {0x158, 16, 16, 7245},
+  {0x0, 5, 6, 7245},
+  {0x2f9c8, 16, 16, 7246},
+  {0x0, 0, 2, 7246},
+  {0x1fc8, 16, 16, 7248},
+  {0x388, 16, 16, 7248},
+  {0x0, 12, 13, 7248},
+  {0xf9cb, 16, 16, 7249},
+  {0x0, 1, 2, 7249},
+  {0xfa62, 16, 16, 7250},
+  {0x0, 9, 10, 7250},
+  {0xf9a9, 16, 16, 7251},
+  {0x0, 14, 15, 7251},
+  {0xf9b6, 16, 16, 7252},
+  {0x0, 5, 6, 7252},
+  {0xf9e3, 16, 16, 7253},
+  {0x0, 11, 12, 7253},
+  {0xf9ce, 16, 16, 7254},
+  {0x0, 3, 4, 7254},
+  {0x1ef5, 16, 16, 7255},
+  {0x0, 1, 2, 7255},
+  {0x1e49, 16, 16, 7256},
+  {0x0, 0, 1, 7256},
+  {0x0, 0, 1, 7257},
+  {0x0, 3, 4, 7258},
+  {0x0, 0, 1, 7259},
+  {0x0, 0, 2, 7260},
+  {0x1f1c, 16, 16, 7262},
+  {0x1f1a, 16, 16, 7262},
+  {0x0, 3, 4, 7262},
+  {0xf99a, 16, 16, 7263},
+  {0xe4, 16, 16, 7263},
+  {0x1ea3, 16, 16, 7263},
+  {0x0, 0, 1, 7263},
+  {0x0, 3, 4, 7264},
+  {0x0, 0, 1, 7265},
+  {0x0, 9, 10, 7266},
+  {0x0, 9, 10, 7267},
+  {0x3054, 16, 16, 7268},
+  {0x0, 1, 3, 7268},
+  {0x2f856, 16, 16, 7270},
+  {0x2f857, 16, 16, 7270},
+  {0xe0, 16, 16, 7270},
+  {0xe1, 16, 16, 7270},
+  {0xe2, 16, 16, 7270},
+  {0xe3, 16, 16, 7270},
+  {0x0, 9, 10, 7270},
+  {0x2f82c, 16, 16, 7271},
+  {0x103, 16, 16, 7271},
+  {0x227, 16, 16, 7271},
+  {0x0, 0, 1, 7271},
+  {0x0, 0, 1, 7272},
+  {0x0, 3, 4, 7273},
+  {0x0, 0, 1, 7274},
+  {0x0, 0, 2, 7275},
+  {0x1f13, 16, 16, 7277},
+  {0x1f15, 16, 16, 7277},
+  {0x0, 1, 2, 7277},
+  {0x2f930, 16, 16, 7278},
+  {0x0, 0, 2, 7278},
+  {0x1f62, 16, 16, 7280},
+  {0x1f64, 16, 16, 7280},
+  {0x0, 2, 3, 7280},
+  {0xf938, 16, 16, 7281},
+  {0x0, 12, 13, 7281},
+  {0xf93b, 16, 16, 7282},
+  {0x0, 6, 7, 7282},
+  {0xf935, 16, 16, 7283},
+  {0x0, 0, 1, 7283},
+  {0x0, 0, 1, 7284},
+  {0x0, 3, 4, 7285},
+  {0x0, 4, 5, 7286},
+  {0x0, 5, 6, 7287},
+  {0x1f8c, 16, 16, 7288},
+  {0x0, 0, 1, 7288},
+  {0x0, 0, 1, 7289},
+  {0x0, 3, 4, 7290},
+  {0x0, 0, 1, 7291},
+  {0x0, 2, 3, 7292},
+  {0x1ed9, 16, 16, 7293},
+  {0xe5, 16, 16, 7293},
+  {0x1ce, 16, 16, 7293},
+  {0x0, 11, 12, 7293},
+  {0x2f9a7, 16, 16, 7294},
+  {0x201, 16, 16, 7294},
+  {0x0, 11, 12, 7294},
+  {0x2f990, 16, 16, 7295},
+  {0x0, 6, 7, 7295},
+  {0x2f85c, 16, 16, 7296},
+  {0x0, 0, 1, 7296},
+  {0x0, 0, 1, 7297},
+  {0x0, 3, 4, 7298},
+  {0x0, 4, 5, 7299},
+  {0x0, 5, 6, 7300},
+  {0x1fa3, 16, 16, 7301},
+  {0x0, 6, 7, 7301},
+  {0x2f9aa, 16, 16, 7302},
+  {0x0, 6, 7, 7302},
+  {0xf9b0, 16, 16, 7303},
+  {0x0, 1, 3, 7303},
+  {0x2f881, 16, 16, 7305},
+  {0x2f882, 16, 16, 7305},
+  {0x0, 2, 3, 7305},
+  {0xf9c1, 16, 16, 7306},
+  {0x0, 2, 7, 7306},
+  {0xfa03, 16, 16, 7311},
+  {0x0, 10, 11, 7311},
+  {0x2f932, 16, 16, 7312},
+  {0x2f966, 16, 16, 7312},
+  {0x0, 10, 11, 7312},
+  {0xf9ec, 16, 16, 7313},
+  {0x1e50, 16, 16, 7313},
+  {0x0, 6, 7, 7313},
+  {0xfa61, 16, 16, 7314},
+  {0x0, 1, 13, 7314},
+  {0x109, 16, 16, 7326},
+  {0x107, 16, 16, 7326},
+  {0x10b, 16, 16, 7326},
+  {0x0, 1, 2, 7326},
+  {0x0, 0, 1, 7327},
+  {0x0, 0, 1, 7328},
+  {0x0, 6, 7, 7329},
+  {0x0, 5, 6, 7330},
+  {0x0, 4, 5, 7331},
+  {0x6c2, 16, 16, 7332},
+  {0x0, 2, 3, 7332},
+  {0xf9bf, 16, 16, 7333},
+  {0x0, 0, 1, 7333},
+  {0x0, 0, 1, 7334},
+  {0x2fa1d, 16, 16, 7335},
+  {0x0, 3, 4, 7335},
+  {0x1ef4, 16, 16, 7336},
+  {0x0, 14, 15, 7336},
+  {0x2f9dd, 16, 16, 7337},
+  {0x0, 0, 4, 7337},
+  {0x2f9c4, 16, 16, 7341},
+  {0x0, 0, 1, 7341},
+  {0x0, 0, 1, 7342},
+  {0x0, 3, 4, 7343},
+  {0x0, 4, 5, 7344},
+  {0x0, 5, 6, 7345},
+  {0x1f87, 16, 16, 7346},
+  {0x2f9c3, 16, 16, 7346},
+  {0x0, 11, 12, 7346},
+  {0xf964, 16, 16, 7347},
+  {0x0, 12, 15, 7347},
+  {0xfa15, 16, 16, 7350},
+  {0xf954, 16, 16, 7350},
+  {0x0, 2, 3, 7350},
+  {0xf946, 16, 16, 7351},
+  {0x0, 0, 1, 7351},
+  {0x0, 0, 1, 7352},
+  {0x0, 3, 4, 7353},
+  {0x0, 3, 4, 7354},
+  {0x0, 8, 9, 7355},
+  {0x2226, 16, 16, 7356},
+  {0x1f79, 16, 16, 7356},
+  {0x0, 0, 1, 7356},
+  {0x0, 0, 1, 7357},
+  {0x0, 3, 4, 7358},
+  {0x0, 3, 4, 7359},
+  {0x0, 8, 9, 7360},
+  {0x21ce, 16, 16, 7361},
+  {0x1d4, 16, 16, 7361},
+  {0x1f7b, 16, 16, 7361},
+  {0x10d, 16, 16, 7361},
+  {0x0, 2, 10, 7361},
+  {0x2f96f, 16, 16, 7369},
+  {0xfa58, 16, 16, 7369},
+};
+
+const unsigned short _wind_canon_next_table[] = {
+  1,
+  0,
+  46,
+  29,
+  15,
+  73,
+  64,
+  11,
+  6,
+  24,
+  38,
+  2,
+  42,
+  722,
+  2119,
+  3,
+  140,
+  1467,
+  221,
+  325,
+  285,
+  682,
+  360,
+  729,
+  1610,
+  635,
+  106,
+  2045,
+  510,
+  2830,
+  0,
+  0,
+  0,
+  0,
+  0,
+  748,
+  1101,
+  4614,
+  273,
+  0,
+  4,
+  0,
+  0,
+  4440,
+  5,
+  0,
+  10,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  97,
+  224,
+  1388,
+  270,
+  249,
+  1440,
+  550,
+  3741,
+  2040,
+  7,
+  419,
+  54,
+  109,
+  883,
+  1230,
+  275,
+  336,
+  4348,
+  0,
+  0,
+  4568,
+  3216,
+  2891,
+  0,
+  0,
+  0,
+  0,
+  1305,
+  0,
+  0,
+  8,
+  4480,
+  937,
+  112,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  9,
+  1532,
+  2106,
+  1144,
+  236,
+  1215,
+  1449,
+  1624,
+  0,
+  0,
+  12,
+  194,
+  1718,
+  1680,
+  3611,
+  217,
+  398,
+  13,
+  0,
+  0,
+  0,
+  0,
+  4477,
+  14,
+  2316,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  328,
+  16,
+  553,
+  3511,
+  17,
+  646,
+  732,
+  426,
+  532,
+  57,
+  0,
+  0,
+  0,
+  278,
+  1790,
+  0,
+  0,
+  658,
+  695,
+  2327,
+  3451,
+  3868,
+  18,
+  666,
+  4417,
+  4518,
+  391,
+  1640,
+  1458,
+  567,
+  340,
+  2209,
+  2458,
+  1747,
+  19,
+  20,
+  21,
+  22,
+  23,
+  1307,
+  304,
+  1254,
+  227,
+  750,
+  51,
+  1120,
+  1576,
+  467,
+  1270,
+  2751,
+  25,
+  1647,
+  183,
+  1785,
+  363,
+  1315,
+  0,
+  1982,
+  0,
+  0,
+  2474,
+  0,
+  1656,
+  0,
+  4178,
+  4486,
+  26,
+  28,
+  27,
+  132,
+  82,
+  346,
+  186,
+  98,
+  0,
+  30,
+  0,
+  0,
+  1028,
+  0,
+  1050,
+  739,
+  113,
+  0,
+  2135,
+  1415,
+  0,
+  4020,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4647,
+  31,
+  3197,
+  0,
+  0,
+  32,
+  33,
+  34,
+  35,
+  36,
+  37,
+  354,
+  809,
+  436,
+  1736,
+  39,
+  547,
+  708,
+  1945,
+  850,
+  367,
+  594,
+  1651,
+  388,
+  416,
+  1251,
+  705,
+  4230,
+  0,
+  1894,
+  0,
+  886,
+  424,
+  40,
+  4586,
+  2250,
+  1941,
+  0,
+  0,
+  4635,
+  41,
+  1224,
+  1391,
+  813,
+  1807,
+  3757,
+  308,
+  442,
+  43,
+  439,
+  121,
+  4198,
+  1596,
+  1298,
+  529,
+  1244,
+  1948,
+  4367,
+  4591,
+  2500,
+  2808,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4473,
+  44,
+  45,
+  239,
+  1073,
+  1218,
+  543,
+  506,
+  124,
+  47,
+  128,
+  772,
+  725,
+  291,
+  3715,
+  357,
+  3693,
+  4339,
+  759,
+  0,
+  2181,
+  0,
+  0,
+  0,
+  3076,
+  48,
+  2065,
+  0,
+  3213,
+  49,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1375,
+  50,
+  1333,
+  0,
+  1993,
+  1665,
+  0,
+  52,
+  0,
+  0,
+  1352,
+  0,
+  3457,
+  53,
+  1249,
+  55,
+  0,
+  0,
+  0,
+  1627,
+  0,
+  0,
+  0,
+  0,
+  1920,
+  56,
+  2143,
+  0,
+  0,
+  0,
+  58,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2970,
+  59,
+  60,
+  61,
+  62,
+  63,
+  65,
+  0,
+  0,
+  0,
+  1683,
+  403,
+  1593,
+  1555,
+  862,
+  2420,
+  151,
+  259,
+  1010,
+  2377,
+  2719,
+  385,
+  2542,
+  0,
+  0,
+  0,
+  826,
+  894,
+  66,
+  610,
+  0,
+  2676,
+  513,
+  90,
+  452,
+  1152,
+  1560,
+  470,
+  3342,
+  0,
+  0,
+  67,
+  0,
+  4191,
+  0,
+  4103,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1443,
+  68,
+  69,
+  70,
+  71,
+  72,
+  539,
+  985,
+  74,
+  1870,
+  0,
+  675,
+  1542,
+  75,
+  0,
+  1085,
+  210,
+  2259,
+  2582,
+  498,
+  295,
+  76,
+  0,
+  3605,
+  0,
+  0,
+  4323,
+  0,
+  0,
+  0,
+  0,
+  1741,
+  77,
+  78,
+  79,
+  80,
+  81,
+  2790,
+  587,
+  0,
+  0,
+  978,
+  1368,
+  83,
+  4492,
+  0,
+  0,
+  161,
+  2601,
+  0,
+  0,
+  628,
+  4245,
+  2052,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2488,
+  2098,
+  1037,
+  84,
+  85,
+  86,
+  87,
+  88,
+  89,
+  372,
+  0,
+  154,
+  0,
+  3528,
+  0,
+  1493,
+  0,
+  91,
+  0,
+  1275,
+  0,
+  4271,
+  0,
+  2079,
+  92,
+  93,
+  94,
+  95,
+  96,
+  3288,
+  1345,
+  1907,
+  99,
+  1176,
+  2738,
+  0,
+  3255,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1615,
+  2341,
+  764,
+  0,
+  0,
+  1103,
+  0,
+  1711,
+  2982,
+  100,
+  143,
+  0,
+  4150,
+  0,
+  0,
+  0,
+  3444,
+  101,
+  102,
+  103,
+  104,
+  105,
+  527,
+  881,
+  0,
+  0,
+  0,
+  0,
+  0,
+  107,
+  0,
+  0,
+  0,
+  4111,
+  4319,
+  0,
+  2519,
+  2853,
+  108,
+  1939,
+  0,
+  0,
+  110,
+  0,
+  0,
+  0,
+  0,
+  3917,
+  0,
+  0,
+  0,
+  2192,
+  1883,
+  1470,
+  1202,
+  111,
+  318,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  114,
+  2770,
+  0,
+  0,
+  115,
+  116,
+  117,
+  118,
+  119,
+  120,
+  4389,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2672,
+  0,
+  2002,
+  0,
+  0,
+  122,
+  123,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  179,
+  925,
+  125,
+  0,
+  0,
+  1310,
+  0,
+  1686,
+  0,
+  0,
+  1571,
+  3387,
+  4056,
+  1539,
+  0,
+  0,
+  3187,
+  126,
+  0,
+  954,
+  127,
+  1047,
+  0,
+  0,
+  1771,
+  0,
+  0,
+  3590,
+  0,
+  3849,
+  3246,
+  0,
+  0,
+  129,
+  0,
+  0,
+  433,
+  130,
+  131,
+  3069,
+  133,
+  197,
+  168,
+  1797,
+  0,
+  0,
+  579,
+  1377,
+  445,
+  2552,
+  460,
+  2528,
+  1957,
+  1845,
+  134,
+  2847,
+  901,
+  1326,
+  3859,
+  3234,
+  1193,
+  993,
+  753,
+  3534,
+  520,
+  2171,
+  2023,
+  135,
+  136,
+  137,
+  138,
+  0,
+  4306,
+  181,
+  182,
+  0,
+  0,
+  0,
+  0,
+  180,
+  0,
+  0,
+  0,
+  0,
+  139,
+  842,
+  1889,
+  1537,
+  0,
+  2198,
+  3252,
+  0,
+  0,
+  0,
+  2711,
+  3762,
+  3357,
+  4313,
+  4259,
+  141,
+  142,
+  144,
+  145,
+  146,
+  147,
+  160,
+  0,
+  0,
+  0,
+  150,
+  0,
+  149,
+  0,
+  148,
+  3760,
+  0,
+  0,
+  0,
+  152,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2861,
+  153,
+  155,
+  156,
+  157,
+  158,
+  159,
+  1382,
+  1759,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  162,
+  163,
+  164,
+  165,
+  166,
+  0,
+  958,
+  799,
+  167,
+  0,
+  175,
+  0,
+  0,
+  0,
+  0,
+  0,
+  177,
+  4413,
+  312,
+  479,
+  792,
+  561,
+  169,
+  3769,
+  3920,
+  1487,
+  230,
+  1065,
+  2427,
+  3365,
+  573,
+  1452,
+  204,
+  170,
+  171,
+  172,
+  962,
+  1366,
+  173,
+  2855,
+  174,
+  0,
+  0,
+  0,
+  176,
+  178,
+  0,
+  0,
+  0,
+  0,
+  220,
+  3165,
+  0,
+  2515,
+  4072,
+  0,
+  3470,
+  2736,
+  685,
+  0,
+  0,
+  0,
+  4065,
+  956,
+  1426,
+  184,
+  185,
+  1529,
+  1199,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1294,
+  252,
+  187,
+  406,
+  263,
+  802,
+  3985,
+  0,
+  0,
+  0,
+  188,
+  0,
+  0,
+  0,
+  2521,
+  0,
+  0,
+  4211,
+  4207,
+  1549,
+  4210,
+  189,
+  190,
+  191,
+  3706,
+  192,
+  193,
+  195,
+  4482,
+  0,
+  0,
+  0,
+  4447,
+  196,
+  3144,
+  0,
+  198,
+  1689,
+  1971,
+  3023,
+  3687,
+  844,
+  1257,
+  816,
+  2650,
+  199,
+  200,
+  201,
+  1569,
+  202,
+  623,
+  1006,
+  203,
+  205,
+  206,
+  207,
+  2194,
+  208,
+  2835,
+  209,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1869,
+  2545,
+  2111,
+  0,
+  0,
+  4458,
+  3207,
+  0,
+  0,
+  3111,
+  491,
+  243,
+  211,
+  212,
+  213,
+  214,
+  215,
+  216,
+  218,
+  0,
+  0,
+  3956,
+  4074,
+  0,
+  0,
+  0,
+  2374,
+  0,
+  2864,
+  0,
+  2217,
+  0,
+  4093,
+  219,
+  4624,
+  0,
+  0,
+  0,
+  0,
+  3181,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1313,
+  0,
+  0,
+  222,
+  223,
+  225,
+  0,
+  960,
+  0,
+  0,
+  0,
+  0,
+  3964,
+  0,
+  2070,
+  0,
+  0,
+  3710,
+  3722,
+  1821,
+  226,
+  228,
+  0,
+  2337,
+  2010,
+  1739,
+  3930,
+  0,
+  2844,
+  0,
+  2205,
+  0,
+  4089,
+  229,
+  231,
+  232,
+  233,
+  234,
+  2125,
+  1147,
+  1504,
+  1852,
+  1853,
+  1854,
+  1855,
+  1856,
+  0,
+  1857,
+  0,
+  1858,
+  1859,
+  0,
+  0,
+  235,
+  0,
+  0,
+  1893,
+  2151,
+  0,
+  0,
+  2478,
+  0,
+  237,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3627,
+  238,
+  3084,
+  0,
+  0,
+  0,
+  240,
+  3098,
+  0,
+  3417,
+  0,
+  2733,
+  288,
+  4042,
+  241,
+  0,
+  3183,
+  242,
+  244,
+  245,
+  246,
+  247,
+  248,
+  1464,
+  1829,
+  0,
+  2409,
+  4575,
+  250,
+  0,
+  1026,
+  0,
+  0,
+  0,
+  0,
+  422,
+  3040,
+  3298,
+  3659,
+  311,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  251,
+  3254,
+  1774,
+  0,
+  0,
+  0,
+  253,
+  0,
+  378,
+  0,
+  2976,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2353,
+  254,
+  255,
+  256,
+  4532,
+  257,
+  262,
+  258,
+  3195,
+  260,
+  0,
+  0,
+  2060,
+  0,
+  0,
+  0,
+  0,
+  3061,
+  261,
+  4183,
+  0,
+  0,
+  0,
+  2127,
+  0,
+  0,
+  0,
+  1703,
+  2090,
+  1263,
+  4685,
+  4693,
+  264,
+  265,
+  266,
+  267,
+  268,
+  269,
+  1017,
+  644,
+  271,
+  4507,
+  4332,
+  0,
+  0,
+  3482,
+  3765,
+  3492,
+  3442,
+  3526,
+  3205,
+  2857,
+  2559,
+  701,
+  272,
+  307,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  274,
+  2989,
+  3322,
+  0,
+  0,
+  1608,
+  4469,
+  0,
+  0,
+  2068,
+  302,
+  1380,
+  276,
+  626,
+  4351,
+  277,
+  3593,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  279,
+  280,
+  281,
+  282,
+  3789,
+  0,
+  0,
+  0,
+  283,
+  284,
+  4369,
+  0,
+  286,
+  0,
+  0,
+  0,
+  3021,
+  3494,
+  1812,
+  0,
+  0,
+  2284,
+  0,
+  0,
+  4465,
+  287,
+  289,
+  290,
+  1317,
+  4386,
+  2437,
+  292,
+  0,
+  0,
+  4656,
+  293,
+  294,
+  2033,
+  4164,
+  296,
+  3461,
+  297,
+  298,
+  299,
+  300,
+  301,
+  1015,
+  0,
+  0,
+  1016,
+  0,
+  0,
+  303,
+  1905,
+  0,
+  2597,
+  2301,
+  305,
+  2348,
+  2104,
+  3179,
+  0,
+  3830,
+  0,
+  2359,
+  306,
+  309,
+  0,
+  477,
+  4208,
+  310,
+  313,
+  314,
+  315,
+  4099,
+  316,
+  4095,
+  317,
+  319,
+  3561,
+  320,
+  321,
+  322,
+  3163,
+  0,
+  323,
+  324,
+  4595,
+  326,
+  4122,
+  2012,
+  0,
+  1788,
+  719,
+  0,
+  2058,
+  0,
+  2075,
+  0,
+  0,
+  0,
+  3390,
+  327,
+  1058,
+  0,
+  712,
+  408,
+  0,
+  0,
+  0,
+  329,
+  1629,
+  1110,
+  330,
+  2162,
+  331,
+  332,
+  333,
+  334,
+  335,
+  0,
+  0,
+  0,
+  339,
+  3940,
+  0,
+  3286,
+  0,
+  0,
+  337,
+  4436,
+  0,
+  1343,
+  871,
+  1287,
+  0,
+  1301,
+  3655,
+  0,
+  2995,
+  338,
+  341,
+  342,
+  343,
+  344,
+  345,
+  347,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3013,
+  0,
+  3885,
+  3735,
+  2293,
+  919,
+  348,
+  0,
+  0,
+  0,
+  0,
+  1396,
+  2223,
+  349,
+  350,
+  351,
+  352,
+  353,
+  2502,
+  0,
+  2168,
+  1591,
+  0,
+  0,
+  355,
+  0,
+  4411,
+  4124,
+  0,
+  1008,
+  3222,
+  402,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  401,
+  0,
+  0,
+  0,
+  0,
+  0,
+  356,
+  3038,
+  0,
+  2386,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  358,
+  359,
+  2866,
+  0,
+  0,
+  0,
+  0,
+  3271,
+  0,
+  361,
+  4641,
+  362,
+  4399,
+  0,
+  364,
+  0,
+  0,
+  0,
+  3883,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3876,
+  0,
+  1922,
+  2314,
+  366,
+  365,
+  3249,
+  1663,
+  1241,
+  1558,
+  1903,
+  2215,
+  368,
+  0,
+  4541,
+  0,
+  687,
+  0,
+  3490,
+  370,
+  369,
+  371,
+  373,
+  374,
+  375,
+  376,
+  377,
+  379,
+  380,
+  381,
+  382,
+  865,
+  0,
+  0,
+  1924,
+  383,
+  384,
+  3670,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  386,
+  387,
+  1408,
+  0,
+  0,
+  2423,
+  0,
+  0,
+  4484,
+  0,
+  2946,
+  0,
+  4633,
+  389,
+  1864,
+  0,
+  0,
+  0,
+  1879,
+  390,
+  392,
+  393,
+  394,
+  3865,
+  0,
+  0,
+  0,
+  395,
+  396,
+  0,
+  0,
+  397,
+  399,
+  0,
+  1969,
+  0,
+  3392,
+  2333,
+  400,
+  404,
+  405,
+  407,
+  1019,
+  0,
+  0,
+  0,
+  2745,
+  0,
+  1136,
+  0,
+  415,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2949,
+  835,
+  409,
+  410,
+  411,
+  412,
+  413,
+  414,
+  653,
+  4423,
+  4176,
+  3845,
+  0,
+  0,
+  0,
+  417,
+  0,
+  0,
+  0,
+  2599,
+  2291,
+  1934,
+  0,
+  0,
+  3574,
+  418,
+  4616,
+  420,
+  4120,
+  0,
+  1510,
+  1862,
+  762,
+  1191,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3095,
+  3484,
+  421,
+  505,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  423,
+  425,
+  999,
+  597,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  427,
+  428,
+  429,
+  430,
+  3914,
+  0,
+  0,
+  0,
+  431,
+  432,
+  434,
+  435,
+  437,
+  1581,
+  1239,
+  0,
+  3895,
+  4677,
+  0,
+  3603,
+  3274,
+  0,
+  0,
+  1507,
+  0,
+  0,
+  3082,
+  438,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1726,
+  4241,
+  4357,
+  703,
+  440,
+  0,
+  1043,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2797,
+  3720,
+  441,
+  2824,
+  0,
+  2177,
+  0,
+  0,
+  1092,
+  1434,
+  0,
+  4525,
+  4317,
+  4409,
+  0,
+  443,
+  3123,
+  459,
+  444,
+  1512,
+  0,
+  855,
+  446,
+  3312,
+  970,
+  0,
+  0,
+  2722,
+  0,
+  0,
+  0,
+  0,
+  1838,
+  447,
+  448,
+  449,
+  450,
+  451,
+  1523,
+  0,
+  0,
+  3410,
+  0,
+  689,
+  0,
+  453,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  875,
+  454,
+  455,
+  456,
+  457,
+  458,
+  1727,
+  0,
+  2305,
+  928,
+  485,
+  461,
+  0,
+  0,
+  2278,
+  0,
+  0,
+  0,
+  0,
+  1823,
+  462,
+  463,
+  464,
+  465,
+  466,
+  1932,
+  0,
+  0,
+  0,
+  468,
+  0,
+  0,
+  1303,
+  0,
+  3423,
+  469,
+  4127,
+  471,
+  4136,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2464,
+  472,
+  473,
+  474,
+  475,
+  476,
+  478,
+  480,
+  481,
+  482,
+  483,
+  0,
+  3191,
+  873,
+  484,
+  486,
+  487,
+  488,
+  489,
+  490,
+  0,
+  0,
+  497,
+  492,
+  493,
+  494,
+  495,
+  496,
+  3810,
+  0,
+  0,
+  0,
+  0,
+  0,
+  604,
+  2380,
+  0,
+  499,
+  500,
+  501,
+  502,
+  503,
+  504,
+  3552,
+  1954,
+  0,
+  0,
+  951,
+  4236,
+  3402,
+  0,
+  0,
+  0,
+  507,
+  0,
+  0,
+  2868,
+  2608,
+  0,
+  0,
+  0,
+  0,
+  0,
+  508,
+  509,
+  3887,
+  4146,
+  0,
+  0,
+  511,
+  0,
+  0,
+  2252,
+  0,
+  2122,
+  512,
+  3117,
+  0,
+  0,
+  0,
+  0,
+  1695,
+  0,
+  888,
+  0,
+  514,
+  515,
+  516,
+  517,
+  518,
+  519,
+  521,
+  522,
+  523,
+  524,
+  0,
+  1296,
+  525,
+  0,
+  0,
+  0,
+  0,
+  0,
+  526,
+  528,
+  2580,
+  0,
+  0,
+  0,
+  0,
+  1991,
+  0,
+  0,
+  0,
+  530,
+  531,
+  3472,
+  786,
+  3153,
+  4618,
+  3901,
+  4217,
+  2388,
+  3042,
+  2452,
+  2697,
+  533,
+  2908,
+  2873,
+  1753,
+  4083,
+  1402,
+  534,
+  535,
+  536,
+  537,
+  538,
+  540,
+  542,
+  541,
+  2449,
+  0,
+  544,
+  1667,
+  934,
+  0,
+  2403,
+  0,
+  3160,
+  0,
+  868,
+  0,
+  1133,
+  3542,
+  2266,
+  2186,
+  545,
+  546,
+  548,
+  4308,
+  0,
+  1670,
+  1967,
+  2289,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3487,
+  549,
+  3702,
+  0,
+  0,
+  0,
+  2401,
+  1428,
+  0,
+  672,
+  1045,
+  551,
+  4289,
+  4500,
+  552,
+  941,
+  554,
+  1337,
+  3724,
+  2535,
+  2509,
+  1599,
+  4665,
+  779,
+  1355,
+  3614,
+  4361,
+  4597,
+  3676,
+  638,
+  3948,
+  555,
+  556,
+  557,
+  1979,
+  0,
+  0,
+  0,
+  558,
+  559,
+  0,
+  0,
+  560,
+  562,
+  563,
+  564,
+  565,
+  0,
+  4475,
+  1430,
+  566,
+  0,
+  0,
+  0,
+  0,
+  4488,
+  568,
+  569,
+  570,
+  571,
+  572,
+  574,
+  575,
+  576,
+  1804,
+  0,
+  577,
+  578,
+  580,
+  581,
+  582,
+  583,
+  584,
+  0,
+  0,
+  0,
+  4239,
+  585,
+  586,
+  1815,
+  588,
+  589,
+  590,
+  591,
+  592,
+  3190,
+  593,
+  3819,
+  0,
+  0,
+  2153,
+  0,
+  0,
+  0,
+  770,
+  0,
+  0,
+  0,
+  2688,
+  0,
+  595,
+  596,
+  598,
+  599,
+  600,
+  601,
+  0,
+  0,
+  0,
+  2004,
+  602,
+  603,
+  605,
+  606,
+  607,
+  608,
+  609,
+  3435,
+  0,
+  0,
+  1585,
+  0,
+  0,
+  611,
+  0,
+  0,
+  617,
+  612,
+  613,
+  614,
+  615,
+  616,
+  950,
+  618,
+  619,
+  620,
+  621,
+  940,
+  622,
+  624,
+  0,
+  0,
+  0,
+  625,
+  627,
+  629,
+  1208,
+  630,
+  631,
+  632,
+  633,
+  634,
+  3269,
+  2006,
+  0,
+  0,
+  0,
+  0,
+  3731,
+  0,
+  4310,
+  636,
+  637,
+  639,
+  640,
+  641,
+  642,
+  643,
+  645,
+  1170,
+  1320,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1832,
+  647,
+  648,
+  649,
+  650,
+  651,
+  0,
+  0,
+  0,
+  2133,
+  3450,
+  652,
+  654,
+  655,
+  4063,
+  3782,
+  0,
+  0,
+  656,
+  657,
+  2885,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  659,
+  660,
+  661,
+  662,
+  663,
+  0,
+  0,
+  0,
+  2063,
+  665,
+  664,
+  667,
+  668,
+  669,
+  670,
+  671,
+  674,
+  0,
+  0,
+  673,
+  676,
+  0,
+  4679,
+  677,
+  678,
+  679,
+  680,
+  681,
+  2966,
+  3324,
+  0,
+  0,
+  683,
+  0,
+  4663,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1117,
+  1149,
+  1567,
+  1865,
+  684,
+  686,
+  688,
+  690,
+  691,
+  692,
+  693,
+  694,
+  696,
+  697,
+  698,
+  699,
+  0,
+  0,
+  0,
+  3891,
+  700,
+  2696,
+  702,
+  0,
+  0,
+  0,
+  0,
+  2247,
+  704,
+  706,
+  1228,
+  800,
+  0,
+  2859,
+  0,
+  0,
+  0,
+  3278,
+  711,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  707,
+  747,
+  3266,
+  0,
+  0,
+  4631,
+  0,
+  777,
+  0,
+  0,
+  0,
+  0,
+  0,
+  709,
+  0,
+  1574,
+  2565,
+  710,
+  1673,
+  713,
+  714,
+  715,
+  716,
+  717,
+  718,
+  720,
+  0,
+  721,
+  3508,
+  0,
+  0,
+  0,
+  4626,
+  0,
+  723,
+  1205,
+  3975,
+  0,
+  1965,
+  2339,
+  776,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  724,
+  2072,
+  3816,
+  0,
+  2900,
+  726,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4115,
+  727,
+  728,
+  4321,
+  0,
+  0,
+  1499,
+  1071,
+  730,
+  731,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3686,
+  2394,
+  2643,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  733,
+  4157,
+  734,
+  735,
+  736,
+  737,
+  738,
+  4197,
+  740,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3966,
+  1159,
+  741,
+  742,
+  743,
+  744,
+  745,
+  746,
+  749,
+  2517,
+  0,
+  0,
+  0,
+  3657,
+  3893,
+  0,
+  1363,
+  0,
+  0,
+  751,
+  752,
+  754,
+  755,
+  756,
+  1867,
+  0,
+  1168,
+  757,
+  758,
+  760,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2623,
+  761,
+  763,
+  765,
+  766,
+  767,
+  768,
+  769,
+  0,
+  3768,
+  771,
+  2350,
+  0,
+  1289,
+  0,
+  0,
+  0,
+  773,
+  0,
+  2914,
+  774,
+  775,
+  778,
+  780,
+  781,
+  782,
+  783,
+  0,
+  0,
+  0,
+  4148,
+  784,
+  785,
+  787,
+  788,
+  789,
+  2219,
+  0,
+  0,
+  0,
+  790,
+  791,
+  0,
+  0,
+  798,
+  793,
+  794,
+  795,
+  4643,
+  0,
+  796,
+  797,
+  801,
+  0,
+  0,
+  0,
+  0,
+  861,
+  803,
+  804,
+  805,
+  806,
+  807,
+  812,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  808,
+  1914,
+  0,
+  2611,
+  0,
+  0,
+  810,
+  0,
+  0,
+  1432,
+  3708,
+  811,
+  1166,
+  0,
+  0,
+  0,
+  1769,
+  0,
+  0,
+  0,
+  0,
+  0,
+  814,
+  841,
+  815,
+  817,
+  818,
+  819,
+  820,
+  0,
+  4659,
+  823,
+  822,
+  821,
+  4098,
+  825,
+  0,
+  0,
+  824,
+  834,
+  833,
+  827,
+  0,
+  0,
+  0,
+  0,
+  2482,
+  0,
+  3996,
+  0,
+  3381,
+  828,
+  829,
+  830,
+  831,
+  832,
+  836,
+  837,
+  838,
+  839,
+  840,
+  843,
+  845,
+  846,
+  847,
+  848,
+  0,
+  1583,
+  4046,
+  849,
+  853,
+  0,
+  0,
+  0,
+  0,
+  854,
+  4005,
+  851,
+  0,
+  4545,
+  0,
+  4593,
+  4394,
+  0,
+  0,
+  2882,
+  0,
+  0,
+  4672,
+  852,
+  856,
+  857,
+  858,
+  859,
+  860,
+  1124,
+  0,
+  0,
+  0,
+  2433,
+  2048,
+  0,
+  0,
+  0,
+  0,
+  3569,
+  0,
+  863,
+  864,
+  866,
+  867,
+  4516,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  869,
+  870,
+  872,
+  874,
+  876,
+  877,
+  878,
+  879,
+  880,
+  4396,
+  882,
+  1658,
+  0,
+  2361,
+  2656,
+  0,
+  0,
+  884,
+  0,
+  1410,
+  0,
+  0,
+  0,
+  4205,
+  916,
+  0,
+  915,
+  0,
+  918,
+  917,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  885,
+  887,
+  889,
+  890,
+  891,
+  892,
+  893,
+  2837,
+  0,
+  4562,
+  0,
+  1926,
+  0,
+  895,
+  0,
+  3048,
+  0,
+  2627,
+  0,
+  3696,
+  0,
+  3645,
+  896,
+  897,
+  898,
+  899,
+  900,
+  902,
+  903,
+  904,
+  905,
+  1292,
+  1638,
+  1952,
+  910,
+  911,
+  908,
+  909,
+  914,
+  0,
+  912,
+  913,
+  906,
+  907,
+  0,
+  0,
+  947,
+  0,
+  0,
+  948,
+  920,
+  921,
+  922,
+  923,
+  924,
+  926,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2229,
+  927,
+  929,
+  930,
+  931,
+  932,
+  933,
+  935,
+  936,
+  939,
+  0,
+  0,
+  0,
+  0,
+  938,
+  942,
+  943,
+  944,
+  2311,
+  0,
+  0,
+  0,
+  945,
+  946,
+  0,
+  0,
+  949,
+  952,
+  953,
+  955,
+  957,
+  959,
+  961,
+  966,
+  967,
+  968,
+  969,
+  963,
+  0,
+  964,
+  965,
+  976,
+  977,
+  0,
+  0,
+  1014,
+  0,
+  0,
+  1013,
+  971,
+  972,
+  973,
+  974,
+  975,
+  979,
+  2660,
+  980,
+  981,
+  982,
+  983,
+  4640,
+  984,
+  1126,
+  0,
+  0,
+  0,
+  986,
+  1472,
+  0,
+  987,
+  0,
+  4686,
+  988,
+  989,
+  990,
+  991,
+  992,
+  994,
+  995,
+  996,
+  997,
+  998,
+  1000,
+  1001,
+  1002,
+  1003,
+  0,
+  0,
+  0,
+  2368,
+  1005,
+  1004,
+  1007,
+  1009,
+  2233,
+  0,
+  0,
+  1011,
+  1012,
+  1018,
+  0,
+  0,
+  0,
+  1025,
+  1020,
+  1021,
+  1022,
+  1412,
+  1023,
+  0,
+  0,
+  2799,
+  4403,
+  1024,
+  1123,
+  0,
+  1119,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1027,
+  0,
+  1036,
+  2442,
+  1029,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1078,
+  1030,
+  0,
+  0,
+  3173,
+  1031,
+  1032,
+  1033,
+  1034,
+  1035,
+  1038,
+  1039,
+  1040,
+  1041,
+  1042,
+  1044,
+  1046,
+  0,
+  0,
+  0,
+  1094,
+  1048,
+  1049,
+  1051,
+  0,
+  0,
+  0,
+  0,
+  4049,
+  0,
+  0,
+  1184,
+  1052,
+  1053,
+  1054,
+  1055,
+  1056,
+  0,
+  3108,
+  1057,
+  1281,
+  1059,
+  1060,
+  1061,
+  1062,
+  1063,
+  1064,
+  1066,
+  1067,
+  1068,
+  1069,
+  1070,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1142,
+  1072,
+  3991,
+  0,
+  1987,
+  0,
+  0,
+  2577,
+  0,
+  2879,
+  0,
+  1074,
+  1709,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1075,
+  1077,
+  0,
+  1076,
+  1079,
+  1080,
+  1081,
+  1082,
+  1083,
+  0,
+  3836,
+  1084,
+  1478,
+  0,
+  0,
+  1086,
+  1095,
+  1087,
+  1088,
+  1089,
+  1090,
+  1091,
+  1093,
+  0,
+  0,
+  1109,
+  1096,
+  1097,
+  1098,
+  1099,
+  1100,
+  1102,
+  1104,
+  1105,
+  1106,
+  1107,
+  1108,
+  1111,
+  4603,
+  1112,
+  1113,
+  1114,
+  1115,
+  1116,
+  3852,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1118,
+  2021,
+  0,
+  0,
+  3625,
+  0,
+  0,
+  2625,
+  2303,
+  2658,
+  0,
+  2589,
+  2904,
+  0,
+  0,
+  1121,
+  1122,
+  0,
+  0,
+  0,
+  1207,
+  1125,
+  2923,
+  0,
+  3373,
+  0,
+  1127,
+  1128,
+  1129,
+  1130,
+  1131,
+  1132,
+  1134,
+  1135,
+  1137,
+  1138,
+  1139,
+  1484,
+  1140,
+  0,
+  0,
+  2785,
+  1143,
+  1141,
+  2440,
+  0,
+  1810,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1145,
+  1146,
+  1151,
+  0,
+  0,
+  0,
+  0,
+  1148,
+  1222,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1150,
+  2414,
+  0,
+  0,
+  3639,
+  0,
+  0,
+  2494,
+  0,
+  0,
+  1153,
+  1154,
+  1155,
+  1156,
+  1157,
+  1158,
+  1214,
+  3089,
+  0,
+  0,
+  0,
+  1160,
+  1161,
+  1162,
+  1163,
+  1164,
+  1165,
+  1204,
+  0,
+  0,
+  0,
+  1167,
+  1169,
+  0,
+  0,
+  0,
+  1183,
+  1171,
+  1172,
+  1173,
+  2506,
+  0,
+  0,
+  0,
+  1174,
+  1175,
+  1177,
+  0,
+  0,
+  0,
+  3127,
+  0,
+  0,
+  0,
+  1233,
+  0,
+  3545,
+  1178,
+  1179,
+  1180,
+  1181,
+  2768,
+  0,
+  1182,
+  0,
+  2776,
+  0,
+  0,
+  2818,
+  1185,
+  3803,
+  1186,
+  1187,
+  1188,
+  3874,
+  0,
+  1189,
+  1190,
+  1192,
+  1194,
+  1195,
+  1196,
+  1197,
+  3087,
+  3425,
+  2425,
+  2781,
+  2782,
+  2779,
+  2780,
+  2778,
+  0,
+  1201,
+  2777,
+  2769,
+  1198,
+  0,
+  0,
+  2823,
+  0,
+  0,
+  2820,
+  1200,
+  1203,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1223,
+  1206,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1227,
+  1209,
+  1210,
+  1211,
+  1212,
+  1213,
+  1216,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3668,
+  1217,
+  2275,
+  0,
+  4212,
+  0,
+  0,
+  1219,
+  0,
+  0,
+  0,
+  0,
+  1660,
+  1220,
+  1221,
+  4558,
+  4353,
+  0,
+  0,
+  0,
+  1225,
+  3785,
+  1885,
+  0,
+  0,
+  1520,
+  0,
+  0,
+  3067,
+  1226,
+  1229,
+  1701,
+  0,
+  0,
+  3309,
+  2997,
+  4002,
+  3661,
+  0,
+  0,
+  0,
+  4397,
+  0,
+  0,
+  4628,
+  1231,
+  1232,
+  1234,
+  1235,
+  1236,
+  1237,
+  1238,
+  1240,
+  1243,
+  1242,
+  3847,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4392,
+  0,
+  1247,
+  0,
+  1245,
+  1654,
+  0,
+  0,
+  2575,
+  1246,
+  1248,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1273,
+  1250,
+  4695,
+  0,
+  0,
+  1252,
+  1605,
+  1253,
+  4203,
+  2043,
+  2363,
+  0,
+  0,
+  3420,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3935,
+  1255,
+  4451,
+  0,
+  2077,
+  4228,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1256,
+  1258,
+  1259,
+  1260,
+  1261,
+  1262,
+  1274,
+  1264,
+  1265,
+  1266,
+  1267,
+  0,
+  0,
+  0,
+  4445,
+  1269,
+  1268,
+  2906,
+  0,
+  0,
+  1271,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1535,
+  0,
+  0,
+  0,
+  2783,
+  1272,
+  1276,
+  1277,
+  1278,
+  1279,
+  1280,
+  1282,
+  1283,
+  1284,
+  1285,
+  1286,
+  1288,
+  1290,
+  1291,
+  1293,
+  3557,
+  3556,
+  0,
+  3560,
+  1295,
+  3525,
+  0,
+  3524,
+  0,
+  3523,
+  3522,
+  1297,
+  1299,
+  3319,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1394,
+  1300,
+  1302,
+  3571,
+  0,
+  0,
+  0,
+  1304,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3624,
+  1306,
+  0,
+  0,
+  0,
+  1336,
+  1308,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3622,
+  3889,
+  0,
+  0,
+  2269,
+  0,
+  1622,
+  1309,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1335,
+  1311,
+  1312,
+  1314,
+  1316,
+  1318,
+  1319,
+  1321,
+  1322,
+  1323,
+  1324,
+  0,
+  0,
+  0,
+  2810,
+  1325,
+  1332,
+  1327,
+  1328,
+  1329,
+  1330,
+  1331,
+  1334,
+  1338,
+  1339,
+  1340,
+  1341,
+  1342,
+  1344,
+  3240,
+  0,
+  0,
+  4006,
+  0,
+  1346,
+  2690,
+  2940,
+  3138,
+  0,
+  4430,
+  0,
+  0,
+  0,
+  4251,
+  1347,
+  1348,
+  1349,
+  1350,
+  1354,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1351,
+  0,
+  1362,
+  1353,
+  1356,
+  1357,
+  1358,
+  1359,
+  0,
+  0,
+  0,
+  4489,
+  1361,
+  1360,
+  1365,
+  0,
+  0,
+  1364,
+  1367,
+  1369,
+  3349,
+  1370,
+  1371,
+  1372,
+  1373,
+  1374,
+  1376,
+  1379,
+  0,
+  0,
+  1378,
+  1425,
+  1381,
+  1383,
+  1384,
+  1385,
+  2029,
+  0,
+  1386,
+  1387,
+  2050,
+  2435,
+  1389,
+  1782,
+  2812,
+  3101,
+  3276,
+  2109,
+  3227,
+  4674,
+  0,
+  4133,
+  1436,
+  0,
+  0,
+  1437,
+  0,
+  1438,
+  0,
+  0,
+  0,
+  1390,
+  1392,
+  0,
+  0,
+  0,
+  0,
+  3712,
+  0,
+  0,
+  0,
+  0,
+  3478,
+  3827,
+  2821,
+  1439,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1393,
+  1395,
+  1397,
+  1398,
+  1399,
+  1400,
+  1401,
+  1403,
+  1404,
+  1405,
+  1406,
+  1407,
+  1409,
+  1411,
+  1414,
+  1413,
+  0,
+  0,
+  1423,
+  0,
+  1424,
+  1416,
+  1417,
+  1418,
+  1419,
+  1420,
+  2413,
+  1421,
+  1422,
+  1427,
+  1429,
+  1431,
+  1433,
+  1435,
+  1860,
+  1441,
+  0,
+  2179,
+  3151,
+  0,
+  3780,
+  0,
+  0,
+  4047,
+  2683,
+  4118,
+  0,
+  0,
+  0,
+  2207,
+  1442,
+  1444,
+  1445,
+  1446,
+  1447,
+  1509,
+  1448,
+  4611,
+  0,
+  0,
+  1765,
+  1450,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3775,
+  0,
+  3134,
+  1451,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1506,
+  1453,
+  1454,
+  1455,
+  2117,
+  0,
+  1456,
+  4549,
+  1502,
+  0,
+  0,
+  0,
+  1503,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1457,
+  1459,
+  1460,
+  1461,
+  1462,
+  1463,
+  1465,
+  1466,
+  1877,
+  4113,
+  4380,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1468,
+  1880,
+  1469,
+  3012,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1471,
+  1473,
+  1474,
+  1475,
+  1476,
+  1477,
+  1479,
+  1480,
+  1481,
+  1482,
+  1483,
+  1486,
+  1485,
+  1488,
+  1489,
+  1490,
+  2470,
+  0,
+  1767,
+  1491,
+  1492,
+  1494,
+  1495,
+  1496,
+  1497,
+  1498,
+  1500,
+  0,
+  0,
+  0,
+  1501,
+  1505,
+  1508,
+  1511,
+  1513,
+  1514,
+  1515,
+  1516,
+  1517,
+  1518,
+  0,
+  1519,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1522,
+  1521,
+  1524,
+  1525,
+  1526,
+  1527,
+  1528,
+  1530,
+  1531,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2637,
+  3193,
+  0,
+  0,
+  4091,
+  1891,
+  0,
+  0,
+  0,
+  0,
+  1533,
+  0,
+  0,
+  0,
+  0,
+  2184,
+  1534,
+  1536,
+  1538,
+  1540,
+  1541,
+  1543,
+  1544,
+  1545,
+  1546,
+  1547,
+  1548,
+  1550,
+  1551,
+  1552,
+  1553,
+  1554,
+  1556,
+  1557,
+  1580,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1579,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3060,
+  1559,
+  1561,
+  1562,
+  1563,
+  1564,
+  1565,
+  1566,
+  1568,
+  1570,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4513,
+  0,
+  0,
+  0,
+  0,
+  4529,
+  0,
+  0,
+  4527,
+  1572,
+  1573,
+  1575,
+  4401,
+  4142,
+  3854,
+  0,
+  3229,
+  2960,
+  0,
+  2287,
+  1943,
+  1613,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1577,
+  1722,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1578,
+  1582,
+  0,
+  0,
+  3268,
+  1584,
+  1586,
+  1587,
+  1588,
+  1589,
+  3081,
+  1590,
+  1592,
+  1636,
+  1594,
+  1595,
+  1597,
+  0,
+  0,
+  0,
+  0,
+  2613,
+  1598,
+  1600,
+  1601,
+  1602,
+  1603,
+  1604,
+  1606,
+  0,
+  0,
+  0,
+  1607,
+  1609,
+  4537,
+  0,
+  0,
+  2254,
+  0,
+  1611,
+  0,
+  0,
+  4428,
+  1612,
+  1614,
+  1616,
+  1897,
+  1617,
+  1618,
+  1619,
+  1620,
+  1621,
+  1623,
+  4530,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1625,
+  1984,
+  1626,
+  1628,
+  3280,
+  1630,
+  1631,
+  1632,
+  1633,
+  1634,
+  1635,
+  1637,
+  1650,
+  0,
+  0,
+  0,
+  1646,
+  1639,
+  0,
+  0,
+  0,
+  0,
+  1672,
+  1641,
+  1642,
+  1643,
+  1644,
+  0,
+  0,
+  0,
+  2937,
+  3683,
+  1645,
+  2324,
+  0,
+  1648,
+  0,
+  3576,
+  0,
+  0,
+  3058,
+  2816,
+  0,
+  4543,
+  1649,
+  1652,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3306,
+  1653,
+  1655,
+  1657,
+  0,
+  0,
+  0,
+  0,
+  1679,
+  1659,
+  3795,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1661,
+  1662,
+  1664,
+  0,
+  3635,
+  1666,
+  2248,
+  0,
+  0,
+  0,
+  1668,
+  0,
+  0,
+  3880,
+  3663,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1669,
+  1671,
+  1674,
+  1675,
+  1676,
+  1677,
+  1678,
+  3620,
+  0,
+  1681,
+  2621,
+  1682,
+  2245,
+  0,
+  2273,
+  0,
+  1684,
+  1685,
+  1687,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2633,
+  0,
+  0,
+  4243,
+  1688,
+  1690,
+  1691,
+  1692,
+  1693,
+  0,
+  2370,
+  1724,
+  1725,
+  0,
+  0,
+  0,
+  0,
+  1723,
+  0,
+  0,
+  0,
+  0,
+  1694,
+  1696,
+  1697,
+  1698,
+  1699,
+  1700,
+  1702,
+  1704,
+  1705,
+  1706,
+  1707,
+  2476,
+  0,
+  0,
+  3467,
+  2062,
+  1708,
+  1710,
+  1712,
+  1713,
+  1714,
+  1715,
+  1717,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1721,
+  0,
+  1716,
+  1719,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3558,
+  1720,
+  1728,
+  1729,
+  1730,
+  1731,
+  1733,
+  1734,
+  0,
+  1732,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1735,
+  1737,
+  0,
+  0,
+  0,
+  0,
+  2271,
+  3843,
+  0,
+  4471,
+  3684,
+  0,
+  4144,
+  1738,
+  1740,
+  1742,
+  1743,
+  1744,
+  1745,
+  1746,
+  1748,
+  1749,
+  1750,
+  1751,
+  1752,
+  1754,
+  1755,
+  1756,
+  1757,
+  1758,
+  1760,
+  1761,
+  1762,
+  2406,
+  0,
+  1763,
+  1764,
+  1766,
+  1851,
+  0,
+  0,
+  0,
+  1844,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1768,
+  1770,
+  1772,
+  1773,
+  1775,
+  1776,
+  1777,
+  1778,
+  2085,
+  0,
+  0,
+  3063,
+  1779,
+  1780,
+  0,
+  0,
+  1784,
+  0,
+  1781,
+  1783,
+  2190,
+  3056,
+  0,
+  0,
+  0,
+  1786,
+  0,
+  0,
+  4535,
+  0,
+  4638,
+  4426,
+  2962,
+  1787,
+  1831,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1789,
+  1791,
+  1792,
+  1793,
+  1794,
+  1795,
+  1796,
+  2014,
+  0,
+  2591,
+  2754,
+  2931,
+  3006,
+  2239,
+  3167,
+  1798,
+  4030,
+  3907,
+  1799,
+  1800,
+  1801,
+  1802,
+  1803,
+  1814,
+  1805,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1806,
+  1808,
+  0,
+  0,
+  0,
+  3672,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2159,
+  1809,
+  1811,
+  1813,
+  1816,
+  1817,
+  1818,
+  1819,
+  1820,
+  3653,
+  1822,
+  1824,
+  1825,
+  1826,
+  1827,
+  1828,
+  1830,
+  1833,
+  1834,
+  1835,
+  3105,
+  0,
+  0,
+  0,
+  1836,
+  1837,
+  1839,
+  1840,
+  1841,
+  1842,
+  1843,
+  1846,
+  1847,
+  1848,
+  2787,
+  0,
+  2149,
+  1849,
+  1850,
+  1861,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1887,
+  1863,
+  3714,
+  0,
+  1866,
+  1868,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1888,
+  2713,
+  0,
+  0,
+  0,
+  0,
+  1871,
+  0,
+  0,
+  4279,
+  1872,
+  1873,
+  1874,
+  1875,
+  1876,
+  1878,
+  1882,
+  0,
+  1881,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1896,
+  1884,
+  1886,
+  1890,
+  1892,
+  1895,
+  1898,
+  1899,
+  1900,
+  1901,
+  1902,
+  1904,
+  1936,
+  0,
+  0,
+  0,
+  1938,
+  0,
+  0,
+  0,
+  1906,
+  0,
+  1916,
+  1908,
+  0,
+  0,
+  0,
+  2801,
+  0,
+  0,
+  0,
+  3821,
+  0,
+  2893,
+  1909,
+  1910,
+  1911,
+  1912,
+  1919,
+  0,
+  1918,
+  0,
+  1913,
+  0,
+  0,
+  1937,
+  1917,
+  0,
+  0,
+  0,
+  1915,
+  1921,
+  1923,
+  1925,
+  1927,
+  1928,
+  1929,
+  1930,
+  1931,
+  1933,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1951,
+  1935,
+  1940,
+  1942,
+  1944,
+  3897,
+  2257,
+  0,
+  0,
+  2685,
+  0,
+  0,
+  0,
+  1946,
+  1947,
+  3840,
+  3567,
+  0,
+  2958,
+  0,
+  0,
+  0,
+  0,
+  1949,
+  3225,
+  1950,
+  1953,
+  1955,
+  1956,
+  1958,
+  1959,
+  1960,
+  1961,
+  2335,
+  2669,
+  2000,
+  2001,
+  1998,
+  1999,
+  1997,
+  0,
+  1995,
+  1996,
+  2008,
+  2009,
+  1964,
+  0,
+  1963,
+  0,
+  0,
+  1962,
+  1966,
+  1968,
+  1986,
+  0,
+  0,
+  0,
+  0,
+  1970,
+  1972,
+  1973,
+  1974,
+  2635,
+  0,
+  1975,
+  2299,
+  1978,
+  0,
+  0,
+  1976,
+  1977,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1990,
+  1981,
+  1980,
+  1983,
+  1985,
+  1988,
+  0,
+  0,
+  0,
+  3394,
+  1989,
+  1992,
+  1994,
+  2003,
+  2005,
+  2007,
+  2011,
+  2013,
+  2015,
+  2016,
+  2017,
+  2018,
+  2020,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2019,
+  2022,
+  2024,
+  2025,
+  2026,
+  2027,
+  4061,
+  3801,
+  4344,
+  4343,
+  4342,
+  2028,
+  4338,
+  0,
+  4337,
+  4336,
+  4335,
+  4334,
+  0,
+  4379,
+  4378,
+  0,
+  0,
+  4371,
+  2032,
+  2031,
+  0,
+  2030,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2039,
+  2034,
+  2035,
+  2036,
+  2037,
+  2038,
+  4329,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2814,
+  0,
+  0,
+  0,
+  2041,
+  0,
+  0,
+  3079,
+  2042,
+  2044,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2087,
+  2365,
+  2046,
+  2047,
+  2049,
+  2097,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2051,
+  2053,
+  2054,
+  2055,
+  2056,
+  2057,
+  2059,
+  2061,
+  2064,
+  2066,
+  2067,
+  2069,
+  2071,
+  3878,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2073,
+  2074,
+  2076,
+  2089,
+  0,
+  2078,
+  2080,
+  2081,
+  2082,
+  2083,
+  2084,
+  2086,
+  2088,
+  2091,
+  2092,
+  2093,
+  2094,
+  0,
+  0,
+  0,
+  3400,
+  2095,
+  2096,
+  2099,
+  2100,
+  2101,
+  2102,
+  2103,
+  2105,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2222,
+  2107,
+  2108,
+  2110,
+  0,
+  2929,
+  2112,
+  2113,
+  2114,
+  2115,
+  2116,
+  2157,
+  2158,
+  0,
+  2161,
+  0,
+  0,
+  0,
+  2156,
+  0,
+  0,
+  0,
+  0,
+  2118,
+  3219,
+  0,
+  0,
+  2120,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2833,
+  2504,
+  2121,
+  2124,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2123,
+  2126,
+  2128,
+  2129,
+  2130,
+  3428,
+  3754,
+  0,
+  0,
+  2131,
+  2132,
+  2134,
+  2136,
+  2137,
+  2138,
+  2139,
+  2140,
+  3777,
+  2141,
+  2142,
+  2144,
+  2145,
+  2146,
+  2147,
+  2148,
+  2150,
+  2152,
+  2189,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2155,
+  0,
+  0,
+  0,
+  0,
+  2154,
+  2160,
+  2163,
+  2164,
+  2165,
+  2166,
+  2167,
+  0,
+  0,
+  0,
+  2170,
+  2169,
+  2172,
+  2173,
+  2174,
+  2175,
+  0,
+  4233,
+  4454,
+  3665,
+  3666,
+  0,
+  3664,
+  0,
+  0,
+  0,
+  3667,
+  0,
+  0,
+  0,
+  0,
+  2176,
+  2232,
+  0,
+  2178,
+  2180,
+  2182,
+  3136,
+  2183,
+  2185,
+  2187,
+  0,
+  0,
+  3185,
+  2188,
+  2191,
+  2193,
+  2202,
+  2201,
+  2204,
+  2203,
+  2197,
+  0,
+  2200,
+  2367,
+  2196,
+  2195,
+  0,
+  2238,
+  2237,
+  0,
+  0,
+  2236,
+  2199,
+  2206,
+  2208,
+  2210,
+  2211,
+  2212,
+  2213,
+  2214,
+  2216,
+  2218,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2235,
+  2221,
+  2220,
+  2224,
+  2225,
+  2226,
+  2227,
+  2228,
+  2230,
+  2231,
+  2234,
+  2240,
+  2241,
+  2242,
+  2871,
+  0,
+  2243,
+  2244,
+  2246,
+  2249,
+  2251,
+  0,
+  0,
+  0,
+  2256,
+  2253,
+  2255,
+  4135,
+  2258,
+  4372,
+  2762,
+  0,
+  0,
+  3000,
+  2260,
+  2261,
+  2262,
+  2263,
+  2264,
+  2265,
+  2267,
+  2268,
+  2270,
+  2272,
+  0,
+  0,
+  0,
+  0,
+  2286,
+  2274,
+  0,
+  2326,
+  2667,
+  2276,
+  2277,
+  2279,
+  2280,
+  2281,
+  2282,
+  2283,
+  2957,
+  0,
+  2956,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2948,
+  2285,
+  2288,
+  2290,
+  2292,
+  2294,
+  2295,
+  2296,
+  2297,
+  2298,
+  2300,
+  2302,
+  2304,
+  2306,
+  2307,
+  2308,
+  2309,
+  2310,
+  2312,
+  2313,
+  2315,
+  2317,
+  2318,
+  2319,
+  2320,
+  2321,
+  2322,
+  2323,
+  2325,
+  2328,
+  2329,
+  2330,
+  2331,
+  0,
+  0,
+  0,
+  3651,
+  3273,
+  2332,
+  2334,
+  0,
+  0,
+  0,
+  2930,
+  2336,
+  2338,
+  2340,
+  2342,
+  3502,
+  2343,
+  2344,
+  2345,
+  2346,
+  2347,
+  2349,
+  2731,
+  2351,
+  2352,
+  2354,
+  2355,
+  2356,
+  2357,
+  3408,
+  3730,
+  2358,
+  4346,
+  0,
+  0,
+  0,
+  2360,
+  2362,
+  2364,
+  2366,
+  2369,
+  2373,
+  0,
+  0,
+  2372,
+  2371,
+  2376,
+  0,
+  0,
+  0,
+  2375,
+  3704,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2378,
+  2379,
+  2381,
+  2382,
+  2383,
+  2384,
+  2385,
+  2387,
+  2389,
+  2390,
+  2391,
+  2392,
+  2393,
+  2395,
+  2396,
+  2397,
+  2398,
+  2399,
+  2400,
+  2402,
+  2404,
+  2405,
+  2407,
+  2408,
+  0,
+  2411,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2412,
+  2410,
+  2415,
+  2416,
+  2417,
+  2418,
+  2419,
+  2480,
+  2421,
+  0,
+  3065,
+  2422,
+  2424,
+  2426,
+  2428,
+  2429,
+  2430,
+  3054,
+  0,
+  2431,
+  3432,
+  2432,
+  0,
+  0,
+  0,
+  3753,
+  2434,
+  2436,
+  2438,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4503,
+  2439,
+  2441,
+  2443,
+  2444,
+  2445,
+  2446,
+  2447,
+  2448,
+  2450,
+  2451,
+  2453,
+  2454,
+  2455,
+  3750,
+  0,
+  0,
+  0,
+  2456,
+  3919,
+  0,
+  0,
+  2457,
+  2459,
+  2460,
+  2461,
+  2462,
+  2463,
+  2465,
+  2466,
+  2467,
+  2468,
+  2469,
+  2473,
+  0,
+  0,
+  0,
+  0,
+  2472,
+  2471,
+  0,
+  0,
+  0,
+  3832,
+  2475,
+  2477,
+  2481,
+  2479,
+  2483,
+  2484,
+  2485,
+  2486,
+  2487,
+  2489,
+  2490,
+  2491,
+  2492,
+  2493,
+  2495,
+  2496,
+  2497,
+  2498,
+  2499,
+  2551,
+  2501,
+  2508,
+  0,
+  0,
+  2503,
+  2541,
+  0,
+  0,
+  0,
+  0,
+  2505,
+  4102,
+  2507,
+  2510,
+  2511,
+  2512,
+  2513,
+  2514,
+  2516,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2564,
+  2518,
+  2520,
+  2522,
+  2523,
+  2524,
+  2525,
+  2827,
+  0,
+  0,
+  3797,
+  2526,
+  2527,
+  3942,
+  4265,
+  4298,
+  0,
+  2529,
+  0,
+  0,
+  0,
+  3359,
+  2530,
+  2531,
+  2532,
+  2533,
+  2534,
+  2536,
+  2537,
+  2538,
+  2539,
+  2540,
+  2543,
+  2544,
+  2546,
+  2547,
+  2548,
+  2549,
+  2550,
+  2553,
+  2567,
+  2917,
+  0,
+  2704,
+  0,
+  0,
+  0,
+  3584,
+  2554,
+  2555,
+  2556,
+  2557,
+  2562,
+  2561,
+  0,
+  2563,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2558,
+  2560,
+  2566,
+  2568,
+  2569,
+  2570,
+  2571,
+  2573,
+  0,
+  0,
+  2574,
+  0,
+  0,
+  0,
+  2572,
+  2610,
+  0,
+  0,
+  0,
+  0,
+  2576,
+  2578,
+  2579,
+  2581,
+  2583,
+  3744,
+  2584,
+  2585,
+  2586,
+  2587,
+  2588,
+  2590,
+  2592,
+  2593,
+  2594,
+  2595,
+  4059,
+  3125,
+  3459,
+  2596,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3767,
+  0,
+  0,
+  0,
+  0,
+  3719,
+  0,
+  0,
+  3718,
+  2598,
+  2600,
+  2602,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2615,
+  2603,
+  2604,
+  2605,
+  3296,
+  0,
+  2606,
+  2607,
+  2609,
+  2612,
+  2614,
+  2616,
+  2617,
+  2618,
+  2619,
+  2620,
+  2622,
+  2624,
+  2626,
+  2628,
+  2629,
+  2630,
+  2631,
+  2632,
+  2634,
+  2636,
+  0,
+  0,
+  0,
+  0,
+  2671,
+  2638,
+  2639,
+  2640,
+  2641,
+  2642,
+  2644,
+  2645,
+  2646,
+  2647,
+  2649,
+  2648,
+  2651,
+  2652,
+  2653,
+  3572,
+  0,
+  2964,
+  2654,
+  2655,
+  2657,
+  2659,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2687,
+  2661,
+  2662,
+  2663,
+  2664,
+  2665,
+  2666,
+  2668,
+  2674,
+  0,
+  2675,
+  0,
+  0,
+  2670,
+  2673,
+  2677,
+  2678,
+  2679,
+  2680,
+  2681,
+  2682,
+  2684,
+  2686,
+  2689,
+  2691,
+  2692,
+  2693,
+  2694,
+  2695,
+  0,
+  2703,
+  2698,
+  2699,
+  2700,
+  3961,
+  0,
+  0,
+  0,
+  2701,
+  2702,
+  0,
+  0,
+  2710,
+  2705,
+  2706,
+  2707,
+  2708,
+  2709,
+  2712,
+  2714,
+  2715,
+  2716,
+  2717,
+  2718,
+  3326,
+  2720,
+  2721,
+  2723,
+  2724,
+  2725,
+  2726,
+  2729,
+  2728,
+  0,
+  2730,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2727,
+  2732,
+  2734,
+  2735,
+  3799,
+  2737,
+  2739,
+  2740,
+  2741,
+  2742,
+  2743,
+  2744,
+  2746,
+  2747,
+  2748,
+  2749,
+  4180,
+  4425,
+  2750,
+  4654,
+  4415,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2752,
+  0,
+  0,
+  4287,
+  2753,
+  2755,
+  2756,
+  2757,
+  3355,
+  0,
+  2758,
+  2759,
+  0,
+  0,
+  2761,
+  2760,
+  2763,
+  2764,
+  2765,
+  2766,
+  2767,
+  2771,
+  2772,
+  2773,
+  4355,
+  2774,
+  2775,
+  2784,
+  2789,
+  0,
+  0,
+  2786,
+  2788,
+  3029,
+  2791,
+  2792,
+  2793,
+  2794,
+  2795,
+  4350,
+  2796,
+  0,
+  4347,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4345,
+  2798,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2826,
+  2807,
+  0,
+  0,
+  2800,
+  2802,
+  2803,
+  2804,
+  2805,
+  2806,
+  2809,
+  2811,
+  2813,
+  2815,
+  2819,
+  2817,
+  2822,
+  2825,
+  2828,
+  2829,
+  2832,
+  0,
+  0,
+  2831,
+  2834,
+  2836,
+  0,
+  0,
+  0,
+  0,
+  2843,
+  2838,
+  2839,
+  2840,
+  2841,
+  2842,
+  2845,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2846,
+  2848,
+  2849,
+  2850,
+  2851,
+  0,
+  3519,
+  3203,
+  2852,
+  0,
+  0,
+  0,
+  0,
+  2863,
+  2854,
+  2856,
+  2858,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2903,
+  2860,
+  2862,
+  2865,
+  2867,
+  2869,
+  3232,
+  2870,
+  2872,
+  2874,
+  2875,
+  2876,
+  2877,
+  2878,
+  2880,
+  2881,
+  2883,
+  0,
+  2884,
+  2886,
+  2887,
+  2888,
+  2889,
+  2890,
+  2899,
+  0,
+  0,
+  0,
+  2892,
+  2894,
+  2895,
+  2896,
+  2897,
+  2898,
+  2901,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4384,
+  2902,
+  2905,
+  2907,
+  2909,
+  2910,
+  2911,
+  2912,
+  2913,
+  2915,
+  2916,
+  2918,
+  2919,
+  2920,
+  2921,
+  2922,
+  2924,
+  2925,
+  2926,
+  2927,
+  2928,
+  2932,
+  2933,
+  2934,
+  2935,
+  0,
+  3601,
+  3899,
+  2968,
+  2969,
+  0,
+  0,
+  0,
+  2936,
+  2939,
+  0,
+  0,
+  2938,
+  2941,
+  2942,
+  2943,
+  2944,
+  2945,
+  2947,
+  2950,
+  2951,
+  2952,
+  2953,
+  3328,
+  2954,
+  2955,
+  2959,
+  3551,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  2961,
+  2963,
+  2965,
+  2967,
+  2971,
+  2972,
+  2973,
+  2974,
+  2975,
+  2977,
+  2978,
+  2979,
+  2980,
+  3302,
+  2991,
+  2992,
+  0,
+  0,
+  2994,
+  0,
+  2993,
+  0,
+  2981,
+  2983,
+  2984,
+  2985,
+  2986,
+  2987,
+  0,
+  2988,
+  2990,
+  2996,
+  0,
+  0,
+  0,
+  2999,
+  2998,
+  3001,
+  3002,
+  3003,
+  3004,
+  3005,
+  3007,
+  3008,
+  3009,
+  3331,
+  3010,
+  3980,
+  3674,
+  3020,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3011,
+  3014,
+  3015,
+  3016,
+  3017,
+  3018,
+  3019,
+  3022,
+  3024,
+  3025,
+  3026,
+  3973,
+  3733,
+  3337,
+  3027,
+  3028,
+  3030,
+  3031,
+  3032,
+  3033,
+  3034,
+  3035,
+  0,
+  3036,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3037,
+  3039,
+  3041,
+  3043,
+  3044,
+  3045,
+  3046,
+  3047,
+  3049,
+  3050,
+  3051,
+  3052,
+  3053,
+  3097,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3055,
+  3057,
+  3059,
+  3062,
+  3064,
+  3066,
+  3104,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3068,
+  3637,
+  4170,
+  3070,
+  3578,
+  3071,
+  3072,
+  3073,
+  3074,
+  3075,
+  3077,
+  3078,
+  3080,
+  3083,
+  3085,
+  3086,
+  3088,
+  3090,
+  3091,
+  3092,
+  3093,
+  4028,
+  3094,
+  3096,
+  3099,
+  3100,
+  3103,
+  0,
+  0,
+  3231,
+  0,
+  3102,
+  3107,
+  3106,
+  3109,
+  3110,
+  3112,
+  3113,
+  3114,
+  3115,
+  3116,
+  3118,
+  3119,
+  3120,
+  3121,
+  3122,
+  3124,
+  3295,
+  3126,
+  0,
+  0,
+  0,
+  3133,
+  3128,
+  3129,
+  3130,
+  3131,
+  3132,
+  3135,
+  3137,
+  3139,
+  3140,
+  3141,
+  3142,
+  3143,
+  0,
+  0,
+  0,
+  4457,
+  0,
+  4464,
+  0,
+  4456,
+  3145,
+  3146,
+  3147,
+  3148,
+  3150,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3149,
+  3159,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3152,
+  3154,
+  3155,
+  3156,
+  3157,
+  3158,
+  3161,
+  3162,
+  3164,
+  3166,
+  0,
+  0,
+  0,
+  0,
+  3224,
+  0,
+  0,
+  3221,
+  3168,
+  3169,
+  3170,
+  3787,
+  0,
+  3171,
+  3172,
+  3174,
+  3175,
+  3176,
+  3177,
+  3178,
+  3180,
+  3182,
+  3184,
+  3186,
+  3188,
+  3189,
+  3192,
+  3194,
+  3196,
+  3198,
+  3199,
+  3200,
+  3201,
+  3202,
+  3204,
+  3218,
+  0,
+  3206,
+  3208,
+  3209,
+  3210,
+  3211,
+  3212,
+  4505,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3214,
+  3215,
+  3217,
+  3220,
+  3223,
+  3226,
+  3265,
+  0,
+  0,
+  3228,
+  3230,
+  3233,
+  3235,
+  3236,
+  3237,
+  3238,
+  0,
+  3838,
+  3264,
+  0,
+  0,
+  0,
+  0,
+  3263,
+  3262,
+  0,
+  0,
+  0,
+  3239,
+  3241,
+  3242,
+  3243,
+  3244,
+  3245,
+  0,
+  3251,
+  3247,
+  3248,
+  3250,
+  3253,
+  3496,
+  3256,
+  3257,
+  3258,
+  3259,
+  3260,
+  3261,
+  3267,
+  3270,
+  3272,
+  3275,
+  3277,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3842,
+  3279,
+  3281,
+  3282,
+  3283,
+  3284,
+  3285,
+  3287,
+  3289,
+  3290,
+  3291,
+  3292,
+  3293,
+  3294,
+  3300,
+  3301,
+  0,
+  3304,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3297,
+  3321,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3299,
+  3303,
+  3305,
+  3308,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3307,
+  0,
+  0,
+  3311,
+  3310,
+  3313,
+  3314,
+  3315,
+  3316,
+  3318,
+  0,
+  0,
+  3317,
+  3320,
+  3323,
+  3325,
+  3327,
+  3329,
+  3330,
+  3333,
+  3332,
+  3335,
+  3334,
+  3336,
+  0,
+  3339,
+  0,
+  3341,
+  3340,
+  3371,
+  3379,
+  4692,
+  0,
+  0,
+  3380,
+  3338,
+  4468,
+  0,
+  0,
+  0,
+  3348,
+  0,
+  0,
+  0,
+  0,
+  3372,
+  3343,
+  3344,
+  3345,
+  3346,
+  3347,
+  3350,
+  3351,
+  3352,
+  3353,
+  3354,
+  3406,
+  3405,
+  0,
+  0,
+  0,
+  0,
+  3407,
+  0,
+  0,
+  0,
+  0,
+  3356,
+  3416,
+  3358,
+  0,
+  4528,
+  3360,
+  3361,
+  3362,
+  3363,
+  3397,
+  3398,
+  0,
+  0,
+  3399,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3364,
+  3366,
+  3367,
+  3368,
+  3369,
+  0,
+  3982,
+  4257,
+  3370,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3396,
+  3374,
+  3375,
+  3376,
+  3377,
+  3378,
+  3382,
+  3383,
+  3384,
+  3385,
+  3386,
+  3388,
+  3389,
+  3391,
+  3393,
+  3395,
+  3401,
+  3403,
+  3404,
+  3422,
+  3409,
+  3411,
+  3412,
+  3413,
+  3414,
+  3415,
+  3418,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4661,
+  3419,
+  3421,
+  3424,
+  3426,
+  0,
+  0,
+  0,
+  0,
+  3427,
+  3429,
+  3430,
+  0,
+  0,
+  3431,
+  0,
+  3434,
+  0,
+  3441,
+  3433,
+  3436,
+  3437,
+  3438,
+  3439,
+  3481,
+  3440,
+  3443,
+  3445,
+  3446,
+  3447,
+  3448,
+  3449,
+  3452,
+  3453,
+  3454,
+  3455,
+  3456,
+  3458,
+  4004,
+  3460,
+  3462,
+  3463,
+  3464,
+  3465,
+  3466,
+  3468,
+  0,
+  0,
+  3469,
+  3489,
+  3471,
+  3473,
+  3474,
+  3475,
+  4588,
+  0,
+  0,
+  0,
+  3476,
+  3480,
+  0,
+  0,
+  3477,
+  3479,
+  3486,
+  0,
+  0,
+  0,
+  0,
+  3483,
+  3485,
+  3488,
+  3491,
+  3493,
+  3495,
+  3497,
+  3498,
+  3499,
+  3500,
+  3501,
+  3503,
+  3504,
+  3505,
+  3506,
+  3507,
+  3510,
+  0,
+  0,
+  0,
+  3509,
+  3512,
+  4579,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4551,
+  4291,
+  3513,
+  3514,
+  3515,
+  3516,
+  3518,
+  3517,
+  3520,
+  0,
+  0,
+  0,
+  3521,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3541,
+  3527,
+  3529,
+  3530,
+  3531,
+  3532,
+  3533,
+  3535,
+  3536,
+  3537,
+  4109,
+  0,
+  3538,
+  3834,
+  3539,
+  0,
+  0,
+  0,
+  3540,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3555,
+  3543,
+  3544,
+  3546,
+  3547,
+  3548,
+  3549,
+  3550,
+  3553,
+  3554,
+  3559,
+  3562,
+  3563,
+  3564,
+  3565,
+  3566,
+  3568,
+  3570,
+  3630,
+  3629,
+  0,
+  0,
+  0,
+  0,
+  3632,
+  0,
+  0,
+  0,
+  0,
+  3573,
+  3575,
+  3577,
+  3579,
+  3580,
+  3581,
+  3582,
+  3583,
+  3585,
+  3586,
+  3587,
+  3588,
+  3599,
+  3600,
+  0,
+  0,
+  3589,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3638,
+  3591,
+  3592,
+  3594,
+  3595,
+  3596,
+  3597,
+  3598,
+  3636,
+  0,
+  0,
+  3633,
+  3634,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3602,
+  3604,
+  3606,
+  3607,
+  3608,
+  3609,
+  3610,
+  3612,
+  3613,
+  3615,
+  3616,
+  3617,
+  3618,
+  3619,
+  3621,
+  3623,
+  3626,
+  3631,
+  0,
+  0,
+  0,
+  3628,
+  3640,
+  3641,
+  3642,
+  3643,
+  3682,
+  3644,
+  3646,
+  3647,
+  3648,
+  3649,
+  3650,
+  3654,
+  0,
+  0,
+  3652,
+  3656,
+  3658,
+  3660,
+  3662,
+  3669,
+  3671,
+  3673,
+  3675,
+  3677,
+  3678,
+  3679,
+  3680,
+  3681,
+  3685,
+  3688,
+  3689,
+  3690,
+  3691,
+  0,
+  4263,
+  3692,
+  3694,
+  3695,
+  3697,
+  3698,
+  3699,
+  3700,
+  3701,
+  3703,
+  3705,
+  4515,
+  3707,
+  0,
+  0,
+  4514,
+  0,
+  4512,
+  0,
+  4524,
+  3709,
+  3711,
+  3713,
+  3716,
+  3717,
+  3721,
+  3723,
+  3725,
+  3726,
+  3727,
+  3728,
+  3729,
+  3732,
+  3734,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3764,
+  3736,
+  3737,
+  3738,
+  3739,
+  3740,
+  3742,
+  0,
+  0,
+  0,
+  0,
+  4510,
+  4304,
+  4285,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4539,
+  3743,
+  3745,
+  3746,
+  3747,
+  3748,
+  3749,
+  3751,
+  3752,
+  3756,
+  3755,
+  3758,
+  3759,
+  3761,
+  3763,
+  3766,
+  3770,
+  3771,
+  3772,
+  3773,
+  3774,
+  3776,
+  3778,
+  0,
+  3779,
+  3781,
+  3783,
+  3784,
+  3786,
+  3794,
+  3793,
+  3792,
+  0,
+  0,
+  0,
+  0,
+  3788,
+  3800,
+  0,
+  3833,
+  3790,
+  3791,
+  3796,
+  3798,
+  3802,
+  0,
+  0,
+  0,
+  0,
+  3809,
+  3804,
+  3805,
+  3806,
+  3807,
+  3808,
+  3811,
+  3812,
+  3813,
+  3814,
+  3815,
+  3817,
+  3818,
+  3820,
+  3822,
+  3823,
+  3824,
+  3825,
+  3826,
+  3828,
+  0,
+  0,
+  3829,
+  3831,
+  3835,
+  3837,
+  3856,
+  0,
+  0,
+  0,
+  3853,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3839,
+  3857,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3841,
+  3858,
+  0,
+  0,
+  0,
+  3844,
+  3882,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3846,
+  3848,
+  3850,
+  3851,
+  3855,
+  3860,
+  3861,
+  3862,
+  4382,
+  0,
+  3863,
+  3864,
+  3866,
+  3867,
+  3869,
+  3870,
+  3871,
+  3872,
+  3873,
+  3875,
+  3877,
+  3879,
+  3881,
+  3884,
+  3886,
+  3888,
+  0,
+  0,
+  0,
+  3937,
+  3890,
+  3892,
+  0,
+  0,
+  3913,
+  3938,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3894,
+  3896,
+  3898,
+  3900,
+  3902,
+  3903,
+  3904,
+  3905,
+  3906,
+  3908,
+  3909,
+  3910,
+  3911,
+  0,
+  4443,
+  4215,
+  3933,
+  3934,
+  0,
+  0,
+  0,
+  0,
+  3932,
+  0,
+  0,
+  0,
+  0,
+  3912,
+  3915,
+  3916,
+  3918,
+  3921,
+  3922,
+  3923,
+  3924,
+  0,
+  4438,
+  3929,
+  3928,
+  0,
+  3927,
+  0,
+  3925,
+  3926,
+  0,
+  0,
+  0,
+  0,
+  3939,
+  3931,
+  3936,
+  3941,
+  3943,
+  3944,
+  3945,
+  3946,
+  3955,
+  3954,
+  0,
+  3947,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3959,
+  3949,
+  3950,
+  3951,
+  3952,
+  3953,
+  3960,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3958,
+  3957,
+  0,
+  0,
+  0,
+  3994,
+  3963,
+  3962,
+  3965,
+  3967,
+  3968,
+  3969,
+  3970,
+  3971,
+  3972,
+  4262,
+  4229,
+  4019,
+  4018,
+  4017,
+  0,
+  4016,
+  0,
+  4014,
+  4013,
+  3979,
+  3978,
+  3977,
+  0,
+  0,
+  3974,
+  3976,
+  4015,
+  4027,
+  0,
+  0,
+  0,
+  4012,
+  0,
+  0,
+  0,
+  0,
+  3981,
+  3984,
+  0,
+  0,
+  0,
+  3983,
+  0,
+  0,
+  0,
+  0,
+  0,
+  3995,
+  3986,
+  3987,
+  3988,
+  3989,
+  3990,
+  3992,
+  3993,
+  3997,
+  3998,
+  3999,
+  4000,
+  4001,
+  4201,
+  0,
+  0,
+  4003,
+  4007,
+  4008,
+  4009,
+  4010,
+  4011,
+  4076,
+  0,
+  4021,
+  4022,
+  4023,
+  4024,
+  4025,
+  4026,
+  4029,
+  4037,
+  4031,
+  4032,
+  4033,
+  4034,
+  0,
+  4547,
+  4039,
+  4038,
+  4041,
+  4040,
+  4035,
+  0,
+  0,
+  4036,
+  4045,
+  4044,
+  4071,
+  4043,
+  4048,
+  4050,
+  4051,
+  4052,
+  4053,
+  4054,
+  4055,
+  4057,
+  4058,
+  4060,
+  4082,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4062,
+  4068,
+  4067,
+  0,
+  0,
+  4069,
+  0,
+  4070,
+  0,
+  4064,
+  4066,
+  4073,
+  4075,
+  4077,
+  4078,
+  4079,
+  4080,
+  4081,
+  4084,
+  4085,
+  4086,
+  4087,
+  4088,
+  4090,
+  4092,
+  4094,
+  4097,
+  0,
+  4096,
+  0,
+  0,
+  4101,
+  4571,
+  4572,
+  4573,
+  4574,
+  4100,
+  0,
+  4577,
+  4578,
+  4560,
+  4561,
+  4609,
+  0,
+  4610,
+  0,
+  0,
+  4613,
+  4104,
+  4105,
+  4106,
+  4107,
+  4108,
+  4110,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4126,
+  4112,
+  4114,
+  4116,
+  4117,
+  4119,
+  4121,
+  4123,
+  4125,
+  4128,
+  4129,
+  4130,
+  4131,
+  4132,
+  4134,
+  4137,
+  4138,
+  4139,
+  4140,
+  4141,
+  4143,
+  0,
+  0,
+  0,
+  4202,
+  4145,
+  4189,
+  0,
+  0,
+  4147,
+  4149,
+  0,
+  0,
+  4156,
+  4151,
+  4152,
+  4153,
+  4154,
+  4155,
+  4158,
+  4159,
+  4160,
+  4161,
+  4163,
+  4162,
+  4165,
+  4166,
+  4167,
+  4168,
+  4169,
+  4171,
+  4172,
+  4173,
+  4174,
+  4175,
+  4177,
+  4179,
+  4182,
+  4181,
+  4184,
+  4185,
+  4186,
+  4187,
+  4188,
+  4190,
+  4192,
+  4193,
+  4194,
+  4195,
+  4196,
+  4199,
+  4200,
+  4204,
+  4206,
+  4209,
+  4223,
+  4213,
+  4214,
+  4216,
+  4218,
+  4219,
+  4220,
+  4221,
+  4222,
+  4224,
+  4225,
+  4226,
+  4227,
+  4232,
+  0,
+  0,
+  4231,
+  4235,
+  0,
+  0,
+  0,
+  4234,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4261,
+  4237,
+  4238,
+  4240,
+  4242,
+  4244,
+  4246,
+  4247,
+  4248,
+  4249,
+  4250,
+  4252,
+  4253,
+  4254,
+  4255,
+  4256,
+  4258,
+  4260,
+  4264,
+  4266,
+  4267,
+  4268,
+  4269,
+  4277,
+  0,
+  0,
+  4270,
+  0,
+  0,
+  0,
+  4278,
+  4272,
+  4273,
+  4274,
+  4275,
+  4276,
+  4280,
+  4281,
+  4282,
+  4283,
+  4284,
+  4286,
+  4288,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4316,
+  4290,
+  4292,
+  4293,
+  4294,
+  4295,
+  4296,
+  4297,
+  4299,
+  4300,
+  4301,
+  4302,
+  4303,
+  4305,
+  4307,
+  4309,
+  4312,
+  4311,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4315,
+  4314,
+  4318,
+  4320,
+  4322,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4360,
+  4324,
+  4325,
+  4326,
+  4327,
+  4328,
+  4330,
+  4331,
+  4333,
+  4340,
+  4341,
+  4349,
+  4352,
+  4354,
+  4356,
+  0,
+  0,
+  0,
+  0,
+  4359,
+  4358,
+  4362,
+  4363,
+  4364,
+  4365,
+  4366,
+  4368,
+  4370,
+  4373,
+  4374,
+  4375,
+  4376,
+  4377,
+  4381,
+  4404,
+  4405,
+  0,
+  4406,
+  0,
+  4407,
+  4408,
+  0,
+  0,
+  0,
+  0,
+  4383,
+  4385,
+  4387,
+  4388,
+  4391,
+  4390,
+  4393,
+  4395,
+  4398,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4414,
+  4400,
+  4402,
+  4410,
+  4412,
+  4416,
+  4418,
+  4419,
+  4420,
+  4421,
+  4422,
+  4424,
+  4427,
+  0,
+  0,
+  0,
+  4449,
+  4450,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4429,
+  4431,
+  4432,
+  4433,
+  4434,
+  4435,
+  4467,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4437,
+  4439,
+  4441,
+  4442,
+  4444,
+  4446,
+  4448,
+  4452,
+  4453,
+  4455,
+  4459,
+  4460,
+  4461,
+  4462,
+  4463,
+  4466,
+  4470,
+  4472,
+  4474,
+  4476,
+  0,
+  0,
+  0,
+  4479,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4499,
+  4478,
+  4481,
+  4483,
+  4485,
+  4487,
+  4490,
+  0,
+  0,
+  4491,
+  4493,
+  4494,
+  4495,
+  4496,
+  4497,
+  4498,
+  4502,
+  0,
+  4501,
+  4504,
+  4506,
+  4508,
+  4509,
+  4511,
+  4517,
+  4519,
+  4520,
+  4521,
+  4522,
+  4523,
+  4526,
+  4531,
+  4533,
+  4534,
+  4536,
+  4538,
+  4540,
+  4542,
+  4544,
+  4546,
+  4548,
+  4550,
+  4552,
+  4553,
+  4554,
+  4555,
+  4557,
+  4556,
+  4559,
+  4563,
+  4564,
+  4565,
+  4566,
+  4567,
+  4570,
+  4569,
+  4576,
+  4580,
+  4581,
+  4582,
+  4583,
+  4584,
+  4585,
+  4587,
+  4589,
+  4590,
+  4592,
+  4594,
+  4596,
+  4598,
+  4599,
+  4600,
+  4601,
+  4602,
+  4604,
+  4605,
+  4606,
+  4607,
+  4608,
+  4612,
+  4615,
+  4617,
+  4619,
+  4620,
+  4621,
+  4622,
+  4623,
+  4625,
+  4627,
+  4629,
+  4630,
+  4632,
+  4637,
+  0,
+  0,
+  0,
+  4634,
+  4636,
+  4639,
+  4642,
+  4645,
+  4644,
+  0,
+  0,
+  0,
+  0,
+  4646,
+  0,
+  0,
+  0,
+  0,
+  4694,
+  4648,
+  4649,
+  4650,
+  4651,
+  4652,
+  4653,
+  4655,
+  4657,
+  4658,
+  4660,
+  4662,
+  4671,
+  0,
+  0,
+  4664,
+  4666,
+  4667,
+  4668,
+  4669,
+  4670,
+  4673,
+  4676,
+  0,
+  4675,
+  4678,
+  4680,
+  4681,
+  4682,
+  4683,
+  4684,
+  4687,
+  4688,
+  4689,
+  4690,
+  4691,
+  4696,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  4697,
+};
+
diff --git a/source/heimdal/lib/wind/normalize_table.h b/source/heimdal/lib/wind/normalize_table.h
new file mode 100644 (file)
index 0000000..90b62e6
--- /dev/null
@@ -0,0 +1,34 @@
+/* normalize_table.h */
+/* Automatically generated at 2008-03-18T11:38:08.923674 */
+
+#ifndef NORMALIZE_TABLE_H
+#define NORMALIZE_TABLE_H 1
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define MAX_LENGTH_CANON 18
+
+struct translation {
+  uint32_t key;
+  unsigned short val_len;
+  unsigned short val_offset;
+};
+
+extern const struct translation _wind_normalize_table[];
+
+extern const uint32_t _wind_normalize_val_table[];
+
+extern const size_t _wind_normalize_table_size;
+
+struct canon_node {
+  uint32_t val;
+  unsigned char next_start;
+  unsigned char next_end;
+  unsigned short next_offset;
+};
+
+extern const struct canon_node _wind_canon_table[];
+
+extern const unsigned short _wind_canon_next_table[];
+#endif /* NORMALIZE_TABLE_H */
diff --git a/source/heimdal/lib/wind/stringprep.c b/source/heimdal/lib/wind/stringprep.c
new file mode 100644 (file)
index 0000000..0beba76
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2004, 2006, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+#include <stdlib.h>
+#include <strings.h>
+#include <errno.h>
+
+RCSID("$Id: stringprep.c 22593 2008-02-12 11:58:01Z lha $");
+
+/**
+ * Process a input UCS4 string according a string-prep profile.
+ *
+ * @param in input UCS4 string to process
+ * @param in_len length of the input string
+ * @param out output UCS4 string
+ * @param out_len length of the output string.
+ * @param flags stringprep profile.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_stringprep(const uint32_t *in, size_t in_len,
+               uint32_t *out, size_t *out_len,
+               wind_profile_flags flags)
+{
+    size_t tmp_len = in_len * 3;
+    uint32_t *tmp = malloc(tmp_len * sizeof(uint32_t));
+    int ret;
+    size_t olen;
+
+    if (tmp == NULL)
+       return ENOMEM;
+
+    ret = _wind_stringprep_map(in, in_len, tmp, &tmp_len, flags);
+    if (ret) {
+       free(tmp);
+       return ret;
+    }
+
+    olen = *out_len;
+    ret = _wind_stringprep_normalize(tmp, tmp_len, tmp, &olen);
+    if (ret) {
+       free(tmp);
+       return ret;
+    }
+    ret = _wind_stringprep_prohibited(tmp, olen, flags);
+    if (ret) {
+       free(tmp);
+       return ret;
+    }
+    ret = _wind_stringprep_testbidi(tmp, olen, flags);
+    if (ret) {
+       free(tmp);
+       return ret;
+    }
+
+    /* Insignificant Character Handling for ldap-prep */
+    if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE) {
+       ret = _wind_ldap_case_exact_attribute(tmp, olen, out, out_len);
+#if 0
+    } else if (flags & WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION) {
+    } else if (flags & WIND_PROFILE_LDAP_NUMERIC) {
+    } else if (flags & WIND_PROFILE_LDAP_TELEPHONE) {
+#endif
+    } else {
+       memcpy(out, tmp, sizeof(out[0]) * olen);
+       *out_len = olen;
+    }
+    free(tmp);
+
+    return ret;
+}
+
+static struct {
+    const char *name;
+    wind_profile_flags flags;
+} profiles[] = {
+    { "nameprep", WIND_PROFILE_NAME },
+    { "saslprep", WIND_PROFILE_SASL },
+    { "ldapprep", WIND_PROFILE_LDAP }
+};
+
+/**
+ * Try to find the profile given a name.
+ *
+ * @param name name of the profile.
+ * @param flags the resulting profile.
+ *
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_profile(const char *name, wind_profile_flags *flags)
+{
+    unsigned int i;
+
+    for (i = 0; i < sizeof(profiles)/sizeof(profiles[0]); i++) {
+       if (strcasecmp(profiles[i].name, name) == 0) {
+           *flags = profiles[i].flags;
+           return 0;
+       }
+    }
+    return WIND_ERR_NO_PROFILE;
+}
diff --git a/source/heimdal/lib/wind/utf8.c b/source/heimdal/lib/wind/utf8.c
new file mode 100644 (file)
index 0000000..c49e805
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2004, 2006, 2007, 2008 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "windlocl.h"
+
+RCSID("$Id: utf8.c 22572 2008-02-05 20:22:39Z lha $");
+
+/**
+ * Convert an UTF-8 string to an UCS4 string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out the resulting UCS4 strint, must be at least
+ * wind_utf8ucs4_length() long.  If out is NULL, the function will
+ * calculate the needed space for the out variable (just like
+ * wind_utf8ucs4_length()).
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs4(const char *in, uint32_t *out, size_t *out_len)
+{
+    const unsigned char *p;
+    size_t o = 0;
+
+    for (p = (const unsigned char *)in; *p != '\0'; ++p) {
+       unsigned c = *p;
+       uint32_t u;
+
+       if (c & 0x80) {
+           if ((c & 0xE0) == 0xC0) {
+               const unsigned c2 = *++p;
+               if ((c2 & 0xC0) == 0x80) {
+                   u =  ((c  & 0x1F) << 6)
+                       | (c2 & 0x3F);
+               } else {
+                   return WIND_ERR_INVALID_UTF8;
+               }
+           } else if ((c & 0xF0) == 0xE0) {
+               const unsigned c2 = *++p;
+               if ((c2 & 0xC0) == 0x80) {
+                   const unsigned c3 = *++p;
+                   if ((c3 & 0xC0) == 0x80) {
+                       u =   ((c  & 0x0F) << 12)
+                           | ((c2 & 0x3F) << 6)
+                           |  (c3 & 0x3F);
+                   } else {
+                       return WIND_ERR_INVALID_UTF8;
+                   }
+               } else {
+                   return WIND_ERR_INVALID_UTF8;
+               }
+           } else if ((c & 0xF8) == 0xF0) {
+               const unsigned c2 = *++p;
+               if ((c2 & 0xC0) == 0x80) {
+                   const unsigned c3 = *++p;
+                   if ((c3 & 0xC0) == 0x80) {
+                       const unsigned c4 = *++p;
+                       if ((c4 & 0xC0) == 0x80) {
+                           u =   ((c  & 0x07) << 18)
+                               | ((c2 & 0x3F) << 12)
+                               | ((c3 & 0x3F) <<  6)
+                               |  (c4 & 0x3F);
+                       } else {
+                           return WIND_ERR_INVALID_UTF8;
+                       }
+                   } else {
+                       return WIND_ERR_INVALID_UTF8;
+                   }
+               } else {
+                   return WIND_ERR_INVALID_UTF8;
+               }
+           } else {
+               return WIND_ERR_INVALID_UTF8;
+           }
+       } else {
+           u = c;
+       }
+       if (out) {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+           out[o] = u;
+       }
+       o++;
+    }
+    *out_len = o;
+    return 0;
+}
+
+/**
+ * Calculate the length of from converting a UTF-8 string to a UCS4
+ * string.
+ *
+ * @param in an UTF-8 string to convert.
+ * @param out_len the length of the resulting UCS4 string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_utf8ucs4_length(const char *in, size_t *out_len)
+{
+    return wind_utf8ucs4(in, NULL, out_len);
+}
+
+static const char first_char[4] = 
+    { 0x00, 0xC0, 0xE0, 0xF0 };
+
+/**
+ * Convert an UCS4 string to a UTF-8 string.
+ *
+ * @param in an UCS4 string to convert.
+ * @param in_len the length input array.
+
+ * @param out the resulting UTF-8 strint, must be at least
+ * wind_ucs4utf8_length() + 1 long (the extra char for the NUL).  If
+ * out is NULL, the function will calculate the needed space for the
+ * out variable (just like wind_ucs4utf8_length()).
+
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs4utf8(const uint32_t *in, size_t in_len, char *out, size_t *out_len)
+{
+    uint32_t ch;
+    size_t i, len, o;
+
+    for (o = 0, i = 0; i < in_len; i++) {
+       ch = in[i];
+       
+       if (ch < 0x80) {
+           len = 1;
+       } else if (ch < 0x800) {
+           len = 2;
+       } else if (ch < 0x10000) {
+           len = 3;
+       } else if (ch <= 0x10FFFF) {
+           len = 4;
+       } else
+           return WIND_ERR_INVALID_UTF32;
+       
+       o += len;
+
+       if (out) {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+
+           switch(len) {
+           case 4:
+               out[3] = (ch | 0x80) & 0xbf;
+               ch = ch << 6;
+           case 3:
+               out[2] = (ch | 0x80) & 0xbf;
+               ch = ch << 6;
+           case 2:
+               out[1] = (ch | 0x80) & 0xbf;
+               ch = ch << 6;
+           case 1:
+               out[0] = ch | first_char[len - 1];
+           }
+       }
+       out += len;
+    }
+    if (out) {
+       if (o + 1 >= *out_len)
+           return WIND_ERR_OVERRUN;
+       *out = '\0';
+    }
+    *out_len = o;
+    return 0;
+}
+
+/**
+ * Calculate the length of from converting a UCS4 string to an UTF-8 string.
+ *
+ * @param in an UCS4 string to convert.
+ * @param in_len the length of UCS4 string to convert.
+ * @param out_len the length of the resulting UTF-8 string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs4utf8_length(const uint32_t *in, size_t in_len, size_t *out_len)
+{
+    return wind_ucs4utf8(in, in_len, NULL, out_len);
+}
+
+/**
+ * Read in an UCS2 from a buffer.
+ *
+ * @param ptr The input buffer to read from.
+ * @param len the length of the input buffer.
+ * @param flags Flags to control the behavior of the function.
+ * @param out the output UCS2, the array must be at least out/2 long.
+ * @param out_len the output length
+ * 
+ * @return returns 0 on success, an wind error code otherwise.
+ * @ingroup wind
+ */
+
+int
+wind_ucs2read(const void *ptr, size_t len, unsigned int *flags,
+             uint16_t *out, size_t *out_len)
+{
+    const unsigned char *p = ptr;
+    int little = ((*flags) & WIND_RW_LE);
+    size_t olen = *out_len;
+
+    /** if len is zero, flags are unchanged */
+    if (len == 0) {
+       *out_len = 0;
+       return 0;
+    }
+
+    /** if len is odd, WIND_ERR_LENGTH_NOT_MOD2 is returned */
+    if (len & 1)
+       return WIND_ERR_LENGTH_NOT_MOD2;
+    
+    /**
+     * If the flags WIND_RW_BOM is set, check for BOM. If not BOM is
+     * found, check is LE/BE flag is already and use that otherwise
+     * fail with WIND_ERR_NO_BOM. When done, clear WIND_RW_BOM and
+     * the LE/BE flag and set the resulting LE/BE flag.
+     */
+    if ((*flags) & WIND_RW_BOM) {
+       uint16_t bom = (p[0] << 8) + p[1];
+       if (bom == 0xfffe || bom == 0xfeff) {
+           little = (bom == 0xfffe);
+           p += 2;
+           len -= 2;
+       } else if (((*flags) & (WIND_RW_LE|WIND_RW_BE)) != 0) {
+           /* little already set */
+       } else
+           return WIND_ERR_NO_BOM;
+       *flags = ((*flags) & ~(WIND_RW_BOM|WIND_RW_LE|WIND_RW_BE));
+       *flags |= little ? WIND_RW_LE : WIND_RW_BE;
+    }
+
+    while (len) {
+       if (olen < 1)
+           return WIND_ERR_OVERRUN;
+       if (little)
+           *out = (p[1] << 8) + p[0];
+       else
+           *out = (p[0] << 8) + p[1];
+       out++; p += 2; len -= 2; olen--;
+    }
+    *out_len -= olen;
+    return 0;
+}
+
+/**
+ * Write an UCS2 string to a buffer.
+ *
+ * @param in The input UCS2 string.
+ * @param in_len the length of the input buffer.
+ * @param flags Flags to control the behavior of the function.
+ * @param ptr The input buffer to write to, the array must be at least
+ * (in + 1) * 2 bytes long.
+ * @param out_len the output length
+ * 
+ * @return returns 0 on success, an wind error code otherwise.
+ * @ingroup wind
+ */
+
+int
+wind_ucs2write(const uint16_t *in, size_t in_len, unsigned int *flags,
+              void *ptr, size_t *out_len)
+{
+    unsigned char *p = ptr;
+    size_t len = *out_len;
+
+    /** If in buffer is not of length be mod 2, WIND_ERR_LENGTH_NOT_MOD2 is returned*/
+    if (len & 1)
+       return WIND_ERR_LENGTH_NOT_MOD2;
+
+    /** On zero input length, flags are preserved */
+    if (in_len == 0) {
+       *out_len = 0;
+       return 0;
+    }
+    /** If flags have WIND_RW_BOM set, the byte order mark is written
+     * first to the output data */
+    if ((*flags) & WIND_RW_BOM) {
+       uint16_t bom = 0xfffe;
+       
+       if (len < 2)
+           return WIND_ERR_OVERRUN;
+
+       if ((*flags) & WIND_RW_LE) {
+           p[0] = (bom >> 8) & 0xff;
+           p[1] = (bom     ) & 0xff;
+       } else {
+           p[1] = (bom     ) & 0xff;
+           p[0] = (bom >> 8) & 0xff;
+       }
+       len -= 2;
+    }
+
+    while (in_len) {
+       /** If the output wont fit into out_len, WIND_ERR_OVERRUN is returned */
+       if (len < 2)
+           return WIND_ERR_OVERRUN;
+       if ((*flags) & WIND_RW_LE) {
+           p[0] = (in[0] >> 8) & 0xff;
+           p[1] = (in[0]     ) & 0xff;
+       } else {
+           p[1] = (in[0]     ) & 0xff;
+           p[0] = (in[0] >> 8) & 0xff;
+       }
+       len -= 2;
+       in_len--;
+       p += 2;
+       in++;
+    }
+    *out_len -= len;
+    return 0;
+}
+
+
+/**
+ * Convert an UCS2 string to a UTF-8 string.
+ *
+ * @param in an UCS2 string to convert.
+ * @param in_len the length of the in UCS2 string.
+ * @param out the resulting UTF-8 strint, must be at least
+ * wind_ucs2utf8_length() long.  If out is NULL, the function will
+ * calculate the needed space for the out variable (just like
+ * wind_ucs2utf8_length()).
+ * @param out_len before processing out_len should be the length of
+ * the out variable, after processing it will be the length of the out
+ * string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs2utf8(const uint16_t *in, size_t in_len, char *out, size_t *out_len)
+{
+    uint16_t ch;
+    size_t i, len, o;
+
+    for (o = 0, i = 0; i < in_len; i++) {
+       ch = in[i];
+       
+       if (ch < 0x80) {
+           len = 1;
+       } else if (ch < 0x800) {
+           len = 2;
+       } else
+           len = 3;
+       
+       o += len;
+
+       if (out) {
+           if (o >= *out_len)
+               return WIND_ERR_OVERRUN;
+
+           switch(len) {
+           case 3:
+               out[2] = (ch | 0x80) & 0xbf;
+               ch = ch << 6;
+           case 2:
+               out[1] = (ch | 0x80) & 0xbf;
+               ch = ch << 6;
+           case 1:
+               out[0] = ch | first_char[len - 1];
+           }
+           out += len;
+       }
+    }
+    if (out) {
+       if (o >= *out_len)
+           return WIND_ERR_OVERRUN;
+       *out = '\0';
+    }
+    *out_len = o;
+    return 0;
+}
+
+/**
+ * Calculate the length of from converting a UCS2 string to an UTF-8 string.
+ *
+ * @param in an UCS2 string to convert.
+ * @param in_len an UCS2 string length to convert.
+ * @param out_len the length of the resulting UTF-8 string.
+ * 
+ * @return returns 0 on success, an wind error code otherwise
+ * @ingroup wind
+ */
+
+int
+wind_ucs2utf8_length(const uint16_t *in, size_t in_len, size_t *out_len)
+{
+    return wind_ucs2utf8(in, in_len, NULL, out_len);
+}
diff --git a/source/heimdal/lib/wind/wind.h b/source/heimdal/lib/wind/wind.h
new file mode 100644 (file)
index 0000000..6921b61
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id: wind.h 22595 2008-02-12 11:59:05Z lha $ */
+
+#ifndef _WIND_H_
+#define _WIND_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <wind_err.h>
+
+typedef unsigned int wind_profile_flags;
+
+#define WIND_PROFILE_NAME                      0x00000001
+#define WIND_PROFILE_SASL                      0x00000002
+#define WIND_PROFILE_LDAP                      0x00000004
+
+#define WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE 0x00010000
+#define WIND_PROFILE_LDAP_CASE_EXACT_ASSERTION 0x00020000
+#define WIND_PROFILE_LDAP_NUMERIC              0x00040000
+#define WIND_PROFILE_LDAP_TELEPHONE            0x00080000
+
+
+/* flags to wind_ucs2read/wind_ucs2write */
+#define WIND_RW_LE     1
+#define WIND_RW_BE     2
+#define WIND_RW_BOM    4
+
+int wind_stringprep(const unsigned *in, size_t in_len,
+                   unsigned *out, size_t *out_len,
+                   wind_profile_flags flags);
+int wind_profile(const char *, wind_profile_flags *);
+
+int wind_punycode_label_toascii(const uint32_t *, size_t,
+                               char *, size_t *);
+
+int wind_utf8ucs4(const char *, uint32_t *, size_t *);
+int wind_utf8ucs4_length(const char *, size_t *);
+
+int wind_ucs4utf8(const uint32_t *, size_t, char *, size_t *);
+int wind_ucs4utf8_length(const uint32_t *, size_t, size_t *);
+
+int wind_ucs2utf8(const uint16_t *, size_t, char *, size_t *);
+int wind_ucs2utf8_length(const uint16_t *, size_t, size_t *);
+
+
+int wind_ucs2read(const void *, size_t, unsigned int *, uint16_t *, size_t *);
+int wind_ucs2write(const uint16_t *, size_t, unsigned int *, void *, size_t *);
+
+#endif /* _WIND_H_ */
diff --git a/source/heimdal/lib/wind/wind_err.et b/source/heimdal/lib/wind/wind_err.et
new file mode 100644 (file)
index 0000000..025c402
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Error messages for the wind library
+#
+# This might look like a com_err file, but is not
+#
+id "$Id: wind_err.et 22559 2008-02-03 16:35:07Z lha $"
+
+error_table wind
+
+prefix WIND_ERR
+error_code NONE,               "No error"
+error_code NO_PROFILE,         "No such profile"
+error_code OVERRUN,            "Buffer overrun"
+error_code UNDERUN,            "Buffer underrun"
+error_code LENGTH_NOT_MOD2,    "Lenght not mod2"
+error_code LENGTH_NOT_MOD4,    "Lenght not mod4"
+error_code INVALID_UTF8,       "Invalid UTF-8 combination in string"
+error_code INVALID_UTF16,      "Invalid UTF-16 combination in string"
+error_code INVALID_UTF32,      "Invalid UTF-32 combination in string"
+error_code NO_BOM,             "No byte order mark (BOM) in string"
+
+end
diff --git a/source/heimdal/lib/wind/windlocl.h b/source/heimdal/lib/wind/windlocl.h
new file mode 100644 (file)
index 0000000..02e8c46
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id: windlocl.h 22582 2008-02-11 20:43:50Z lha $ */
+
+#ifndef _WINDLOCL_H_
+#define _WINDLOCL_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "wind.h"
+#include "wind_err.h"
+
+int _wind_combining_class(uint32_t);
+
+int _wind_stringprep_testbidi(const uint32_t *, size_t, wind_profile_flags);
+
+int _wind_stringprep_error(const uint32_t, wind_profile_flags);
+
+int _wind_stringprep_prohibited(const uint32_t *, size_t, wind_profile_flags);
+
+int _wind_stringprep_map(const uint32_t *, size_t,
+                        uint32_t *, size_t *,
+                        wind_profile_flags);
+
+int _wind_stringprep_normalize(const uint32_t *, size_t, uint32_t *, size_t *);
+
+int _wind_ldap_case_exact_attribute(const uint32_t *, size_t,
+                                   uint32_t *, size_t *);
+
+
+#endif /* _WINDLOCL_H_ */
index 45bfd8e81f0a79f13b4355c16287f916d403167d..65b49b73dbd496820c5eb427482b9b9618af500b 100644 (file)
@@ -40,6 +40,7 @@ PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_HCRYPTO HEIMDAL_KRB5 \
 CFLAGS = -Iheimdal_build -Iheimdal/lib/hdb
 OBJ_FILES = \
        ../heimdal/lib/hdb/db.o \
+       ../heimdal/lib/hdb/dbinfo.o \
        ../heimdal/lib/hdb/hdb.o \
        ../heimdal/lib/hdb/ext.o \
        ../heimdal/lib/hdb/keytab.o \
@@ -170,7 +171,7 @@ PUBLIC_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_KRB5
 # Start SUBSYSTEM HEIMDAL_KRB5
 [SUBSYSTEM::HEIMDAL_KRB5]
 CFLAGS = -Iheimdal_build -Iheimdal/lib/krb5 
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND
 PUBLIC_DEPENDENCIES = HEIMDAL_KRB5_ASN1 HEIMDAL_GLUE HEIMDAL_HX509 HEIMDAL_HCRYPTO
 OBJ_FILES = \
        ../heimdal/lib/krb5/acache.o \
@@ -323,7 +324,9 @@ OBJ_FILES = \
        ../heimdal/lib/hcrypto/rand-unix.o \
        ../heimdal/lib/hcrypto/rand-fortuna.o \
        ../heimdal/lib/hcrypto/rand-timer.o \
-       ../heimdal/lib/hcrypto/hmac.o
+       ../heimdal/lib/hcrypto/hmac.o \
+       ../heimdal/lib/hcrypto/camellia.o \
+       ../heimdal/lib/hcrypto/camellia-ntt.o
 # End SUBSYSTEM HEIMDAL_HCRYPTO
 #######################
 
@@ -337,7 +340,8 @@ PRIVATE_DEPENDENCIES = \
        HEIMDAL_CMS_ASN1 HEIMDAL_RFC2459_ASN1 \
        HEIMDAL_OCSP_ASN1 HEIMDAL_PKCS8_ASN1 \
        HEIMDAL_PKCS9_ASN1 HEIMDAL_PKCS12_ASN1 \
-       HEIMDAL_PKINIT_ASN1 HEIMDAL_PKCS10_ASN1
+       HEIMDAL_PKINIT_ASN1 HEIMDAL_PKCS10_ASN1 \
+       HEIMDAL_WIND
 OBJ_FILES = \
        ../heimdal/lib/hx509/ca.o \
        ../heimdal/lib/hx509/cert.o \
@@ -365,6 +369,30 @@ OBJ_FILES = \
 # End SUBSYSTEM HEIMDAL_HX509
 #######################
 
+#######################
+# Start SUBSYSTEM HEIMDAL_WIND
+[SUBSYSTEM::HEIMDAL_WIND]
+CFLAGS = -Iheimdal_build -Iheimdal/lib/wind 
+PRIVATE_DEPENDENCIES = \
+       HEIMDAL_ROKEN HEIMDAL_COM_ERR
+OBJ_FILES = \
+       ../heimdal/lib/wind/wind_err.o \
+       ../heimdal/lib/wind/stringprep.o \
+       ../heimdal/lib/wind/errorlist.o \
+       ../heimdal/lib/wind/errorlist_table.o \
+       ../heimdal/lib/wind/normalize.o \
+       ../heimdal/lib/wind/normalize_table.o \
+       ../heimdal/lib/wind/combining.o \
+       ../heimdal/lib/wind/combining_table.o \
+       ../heimdal/lib/wind/utf8.o \
+       ../heimdal/lib/wind/bidi.o \
+       ../heimdal/lib/wind/bidi_table.o \
+       ../heimdal/lib/wind/ldap.o \
+       ../heimdal/lib/wind/map.o \
+       ../heimdal/lib/wind/map_table.o
+# End SUBSYSTEM HEIMDAL_WIND
+#######################
+
 [SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME]
 CFLAGS = -Iheimdal_build -Iheimdal/lib/roken  -Ilib/socket_wrapper
 OBJ_FILES = ../heimdal/lib/roken/getprogname.o
@@ -415,7 +443,7 @@ PUBLIC_DEPENDENCIES = \
                        HEIMDAL_ROKEN_GETPROGNAME \
                        HEIMDAL_ROKEN_CLOSEFROM \
                        RESOLV \
-                       EXT_SOCKET
+                       LIBREPLACE_NETWORK
 # End SUBSYSTEM HEIMDAL_ROKEN
 #######################
 
@@ -475,7 +503,7 @@ OBJ_FILES = \
        ../heimdal/lib/vers/print_version.ho \
        ../lib/socket_wrapper/socket_wrapper.ho \
        replace.ho
-PRIVATE_DEPENDENCIES = HEIMDAL_ASN1_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = HEIMDAL_ASN1_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H LIBREPLACE_NETWORK
 
 # End BINARY asn1_compile
 #######################
@@ -502,7 +530,7 @@ OBJ_FILES = ../heimdal/lib/vers/print_version.ho \
        ../heimdal/lib/roken/setprogname.ho \
        ../lib/socket_wrapper/socket_wrapper.ho \
        replace.ho
-PRIVATE_DEPENDENCIES = HEIMDAL_COM_ERR_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = HEIMDAL_COM_ERR_COMPILE_LEX HEIMDAL_ROKEN_GETPROGNAME_H LIBREPLACE_NETWORK
 # End BINARY compile_et
 #######################
 
@@ -532,6 +560,7 @@ mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb_err.et heimdal/li
 mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/krb5/krb5_err.et heimdal/lib/krb5|
 mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/gssapi/krb5/gkrb5_err.et heimdal/lib/gssapi|
 mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/hx509/hx509_err.et heimdal/lib/hx509|
+mkinclude perl_path_wrapper.sh et_deps.pl heimdal/lib/wind/wind_err.et heimdal/lib/wind|
 
 clean::        
        @-rm -f bin/compile_et bin/asn1_compile
index 92a5dc26e0adb460e1cf49de6ca569c05e7c0369..72b5bb14a93c531b266d67a105def35e45632119 100644 (file)
@@ -639,9 +639,9 @@ static void kdc_task_init(struct task_server *task)
        }
 
        /* Registar WinDC hooks */
-       ret = _krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
-                                   PLUGIN_TYPE_DATA, "windc",
-                                   &windc_plugin_table);
+       ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 
+                                  PLUGIN_TYPE_DATA, "windc",
+                                  &windc_plugin_table);
        if(ret) {
                task_server_terminate(task, "kdc: failed to register hdb keytab");
                return;
index d88f82b726fe738dd2d50cd1e3ee16c62cdd49b2..a53c5542da3f0411c3895b7035c19e317081c2fa 100644 (file)
@@ -121,7 +121,7 @@ distclean:: clean
        rm -f Makefile
 
 realdistclean:: distclean
-       rm -f configure.in include/config.h.in
+       rm -f configure include/config.h.in
 
 check:: test @PYTHON_CHECK_TARGET@
 
index 3c9ef3ff6939f8095952e48766318be9bb52500c..b51c28899382f2914444fc60746e1dcef62c3695 100644 (file)
@@ -65,7 +65,7 @@ static struct backends_list_entry {
 
 #ifdef HAVE_LDB_LDAP
 #define LDAP_INIT &ldb_ldap_backend_ops, \
-                                 &ldb_ildap_backend_ops, \
+                                 &ldb_ldapi_backend_ops, \
                                  &ldb_ldaps_backend_ops,
 #else
 #define LDAP_INIT
index 7da7b9ba34d073534947978d749d45cbe8817a9d..34e0afbf935f55651a02b62f9d449dfcc41406c9 100644 (file)
@@ -129,11 +129,11 @@ static struct ops_list_entry {
 #ifndef STATIC_LIBLDB_MODULES
 
 #define STATIC_LIBLDB_MODULES \
-       ldb_operational_module_ops,     \
-       ldb_rdn_name_module_ops,        \
-       ldb_paged_results_module_ops,   \
-       ldb_sort_module_ops,            \
-       ldb_asq_module_ops, \
+       &ldb_operational_module_ops,    \
+       &ldb_rdn_name_module_ops,       \
+       &ldb_paged_results_module_ops,  \
+       &ldb_server_sort_module_ops,    \
+       &ldb_asq_module_ops, \
        NULL
 #endif
 
index e2bcca2b04ba017ed299abba4f1ff5e3c4aabbf1..cc9b46ac1ffbbfa9f59dce5b0dc70da7504e6d15 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "replace.h"
 #include "system/filesys.h"
-#include "system/network.h"
 #include "system/time.h"
 #include "talloc.h"
 #include "ldb.h"
index d2dcc675a58a6b380992c2f3ab26feef7feabe86..0ffba9d99baa8bcf324cfbf015b23302864198b5 100644 (file)
@@ -185,7 +185,7 @@ extern const struct ldb_module_ops ldb_paged_results_module_ops;
 extern const struct ldb_module_ops ldb_rdn_name_module_ops;
 extern const struct ldb_module_ops ldb_schema_module_ops;
 extern const struct ldb_module_ops ldb_asq_module_ops;
-extern const struct ldb_module_ops ldb_sort_module_ops;
+extern const struct ldb_module_ops ldb_server_sort_module_ops;
 extern const struct ldb_module_ops ldb_ldap_module_ops;
 extern const struct ldb_module_ops ldb_ildap_module_ops;
 extern const struct ldb_module_ops ldb_tdb_module_ops;
@@ -194,7 +194,7 @@ extern const struct ldb_module_ops ldb_sqlite3_module_ops;
 extern const struct ldb_backend_ops ldb_tdb_backend_ops;
 extern const struct ldb_backend_ops ldb_sqlite3_backend_ops;
 extern const struct ldb_backend_ops ldb_ldap_backend_ops;
-extern const struct ldb_backend_ops ldb_ildap_backend_ops;
+extern const struct ldb_backend_ops ldb_ldapi_backend_ops;
 extern const struct ldb_backend_ops ldb_ldaps_backend_ops;
 
 int ldb_match_msg(struct ldb_context *ldb,
index 3f6ff3fd5b8edadec611adb65f8119e6d0a674c3..a4534c549ad93a7fd9d70245c521dde7af1ce4bd 100644 (file)
@@ -826,17 +826,17 @@ failed:
        return -1;
 }
 
-_PUBLIC_ struct ldb_backend_ops ldb_ldap_backend_ops = {
+const struct ldb_backend_ops ldb_ldap_backend_ops = {
        .name = "ldap",
        .connect_fn = lldb_connect
 };
 
-_PUBLIC_ struct ldb_backend_ops ldb_ldapi_backend_ops = {
+const struct ldb_backend_ops ldb_ldapi_backend_ops = {
        .name = "ldapi",
        .connect_fn = lldb_connect
 };
 
-_PUBLIC_ struct ldb_backend_ops ldb_ldaps_backend_ops = {
+const struct ldb_backend_ops ldb_ldaps_backend_ops = {
        .name = "ldaps",
        .connect_fn = lldb_connect
 };
index 534ba016ab7df25ab58a157816ac427441e8e7e2..ff5dc027429022ac65ae1c595540328e6ad758df 100644 (file)
@@ -7,7 +7,7 @@ ctags:
 .SUFFIXES: _wrap.c .i
 
 .i_wrap.c:
-       [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -python -keyword $<
+       [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -python -keyword $<
 
 .SUFFIXES: .1 .1.xml .3 .3.xml .xml .html .c .o
 
index 98d8e865dd07813eb0d3b6c4be194a710d023c63..1a9e72c907b23976a7cac2aa8de6bc5075012b06 100644 (file)
@@ -32,7 +32,7 @@ int sample_add(struct ldb_module *mod, struct ldb_request *req)
        return ldb_next_request(mod, req);
 }
 
-_PUBLIC_ const struct ldb_module_ops ldb_sample_module_ops = {
+const struct ldb_module_ops ldb_sample_module_ops = {
        .name              = "sample",
        .add               = sample_add,
 };
index c42c9b22bae9f4f598735849d7831eb79755a79c..da6d57541e59fe42cf585dc3100509624762e9f5 100755 (executable)
@@ -19,7 +19,7 @@ fi
 
 cat <<EOF | $VALGRIND ldbadd || exit 1
 dn: @MODULES
-@LIST: sample_module
+@LIST: sample
 EOF
 
 cat <<EOF | $VALGRIND ldbadd || exit 1
index 6a879ab962774f8008af09b56aea34b949042b37..29d6e002477bc1376e5b1d004f88a765a4cb8bbe 100644 (file)
@@ -462,6 +462,8 @@ NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server,
        rec->retries       = 0;
        rec->msg              = msg;
        rec->header           = (struct messaging_header *)rec->packet.data;
+       /* zero padding */
+       ZERO_STRUCTP(rec->header);
        rec->header->version  = MESSAGING_VERSION;
        rec->header->msg_type = msg_type;
        rec->header->from     = msg->server_id;
index c5741b7e2c9fbe08831913efc96aba02d236f17b..51c255e9f7034de850d10340fa5856dcfdf9d786 100644 (file)
@@ -2950,7 +2950,7 @@ SWIGINTERN PyObject *_wrap_Registry(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
   }
   result = reg_open_local(arg1,arg2,arg3,arg4);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3001,7 +3001,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key_by_name(PyObject *SWIGUNUSEDPA
   arg3 = (struct registry_key **)(argp3);
   result = reg_get_predefined_key_by_name(arg1,(char const *)arg2,arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3044,7 +3044,7 @@ SWIGINTERN PyObject *_wrap_reg_key_del_abs(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg2 = (char *)(buf2);
   result = reg_key_del_abs(arg1,(char const *)arg2);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3095,7 +3095,7 @@ SWIGINTERN PyObject *_wrap_reg_get_predefined_key(PyObject *SWIGUNUSEDPARM(self)
   arg3 = (struct registry_key **)(argp3);
   result = reg_get_predefined_key(arg1,arg2,arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3136,7 +3136,7 @@ SWIGINTERN PyObject *_wrap_reg_diff_apply(PyObject *SWIGUNUSEDPARM(self), PyObje
   arg2 = (char *)(buf2);
   result = reg_diff_apply(arg1,(char const *)arg2);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3194,7 +3194,7 @@ SWIGINTERN PyObject *_wrap_reg_generate_diff(PyObject *SWIGUNUSEDPARM(self), PyO
   }
   result = reg_generate_diff(arg1,arg2,(struct reg_diff_callbacks const *)arg3,arg4);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3260,7 +3260,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_0(PyObject *SWIGUNUSEDPARM(self)
   }
   result = reg_mount_hive(arg1,arg2,arg3,(char const **)arg4);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3373,7 +3373,7 @@ SWIGINTERN PyObject *_wrap_reg_mount_hive__SWIG_1(PyObject *SWIGUNUSEDPARM(self)
   arg3 = (char *)(buf3);
   result = reg_mount_hive__SWIG_1(arg1,arg2,(char const *)arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3524,7 +3524,7 @@ SWIGINTERN PyObject *_wrap_hive_key(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
   }
   result = reg_open_hive(arg1,(char const *)arg2,arg3,arg4,arg5,arg6);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3601,7 +3601,7 @@ SWIGINTERN PyObject *_wrap_open_ldb(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
   }
   result = reg_open_ldb_file(arg1,(char const *)arg2,arg3,arg4,arg5,arg6);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3642,7 +3642,7 @@ SWIGINTERN PyObject *_wrap_create_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *
   arg2 = (char *)(buf2);
   result = reg_create_directory(arg1,(char const *)arg2,arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3683,7 +3683,7 @@ SWIGINTERN PyObject *_wrap_open_dir(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
   arg2 = (char *)(buf2);
   result = reg_open_directory(arg1,(char const *)arg2,arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3750,7 +3750,7 @@ SWIGINTERN PyObject *_wrap_open_samba(PyObject *SWIGUNUSEDPARM(self), PyObject *
   }
   result = reg_open_samba(arg1,arg2,arg3,arg4,arg5);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
index 268a1b15cf350ae227edef0d8321553e7d7b1b8c..43f7b08572ff1412f52e3aab0f15fd27212d9ef1 100644 (file)
@@ -15,7 +15,6 @@ rename
 initgroups
 memmove
 strdup
-inet_ntoa
 setlinebuf
 vsyslog
 timegm
@@ -52,6 +51,7 @@ readline (the library)
 inet_ntoa
 inet_ntop
 inet_pton
+inet_aton
 strtoll
 strtoull
 socketpair
index f5e054f4767379ef98714c306638cf8003c9917e..02dc08bf72c269e58ed15c6891347fbc1dd716aa 100644 (file)
@@ -21,6 +21,9 @@ if test "$ac_cv_prog_gcc" = yes; then
    CFLAGS="$CFLAGS -Wno-format-y2k"
 fi
 
+LIBS="${LIBREPLACE_NETWORK_LIBS}"
+AC_SUBST(LIBS)
+
 AC_SUBST(LDFLAGS)
 
 AC_OUTPUT(Makefile)
index 6cca155de3721cc7dc540d42b2ed9530133bb6ec..927bc677db5656bc3a5fc70c83849959693362ac 100644 (file)
@@ -34,10 +34,12 @@ fi
 ##################
 # look for a method of finding the list of network interfaces
 #
-# This tests need LIBS="$NSL_LIBS $SOCKET_LIBS"
+# This tests need LIBS="${LIBREPLACE_NETWORK_LIBS}"
 #
 old_LIBS=$LIBS
-LIBS="$NSL_LIBS $SOCKET_LIBS"
+LIBS="${LIBREPLACE_NETWORK_LIBS}"
+SAVE_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS -I$libreplacedir"
 iface=no;
 ##################
 # look for a method of finding the list of network interfaces
@@ -79,7 +81,6 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available])
-       old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
@@ -100,7 +101,6 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available])
-       old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
@@ -120,8 +120,9 @@ AC_TRY_RUN([
            libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)])
 if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then
     iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available])
-       old_LIBS="$old_LIBS $LIBS"
 fi
 fi
 
 LIBS=$old_LIBS
+CPPFLAGS="$SAVE_CPPFLAGS"
+
index d91d029f6a79ced4089af86cb0b4d0a97b77b608..73333b902199b92d6627f2c1794124ebf7922ce8 100644 (file)
@@ -185,7 +185,13 @@ char *rep_getpass(const char *prompt)
        buf[0] = 0;
        if (!gotintr) {
                in_fd = fileno(in);
-               fgets(buf, bufsize, in);
+               if (fgets(buf, bufsize, in) == NULL) {
+                       buf[0] = 0;
+                       if (in && in != stdin) {
+                               fclose(in);
+                       }
+                       return buf;
+               }
        }
        nread = strlen(buf);
        if (nread) {
diff --git a/source/lib/replace/inet_aton.c b/source/lib/replace/inet_aton.c
new file mode 100644 (file)
index 0000000..c6b3bb1
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement functions
+ * Copyright (C) Michael Adam <obnox@samba.org> 2008
+ *
+ *  ** NOTE! The following LGPL license applies to the replace
+ *  ** library. This does NOT imply that all of Samba is released
+ *  ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+/**
+ * We know that we have inet_pton from earlier libreplace checks.
+ */
+int rep_inet_aton(const char *src, struct in_addr *dst)
+{
+       return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0;
+}
diff --git a/source/lib/replace/inet_aton.m4 b/source/lib/replace/inet_aton.m4
new file mode 100644 (file)
index 0000000..853688e
--- /dev/null
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(inet_aton,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_aton.o"])
diff --git a/source/lib/replace/inet_ntoa.c b/source/lib/replace/inet_ntoa.c
new file mode 100644 (file)
index 0000000..e3b80eb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement routines for broken systems
+ * Copyright (C) Andrew Tridgell 2003
+ * Copyright (C) Michael Adam 2008
+ *
+ *  ** NOTE! The following LGPL license applies to the replace
+ *  ** library. This does NOT imply that all of Samba is released
+ *  ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+/**
+ * NOTE: this is not thread safe, but it can't be, either
+ * since it returns a pointer to static memory.
+ */
+char *rep_inet_ntoa(struct in_addr ip)
+{
+       uint8_t *p = (uint8_t *)&ip.s_addr;
+       static char buf[18];
+       slprintf(buf, 17, "%d.%d.%d.%d",
+                (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
+       return buf;
+}
diff --git a/source/lib/replace/inet_ntoa.m4 b/source/lib/replace/inet_ntoa.m4
new file mode 100644 (file)
index 0000000..5aaa935
--- /dev/null
@@ -0,0 +1,19 @@
+AC_CHECK_FUNCS(inet_ntoa,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_ntoa.o"])
+
+AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[
+AC_TRY_RUN([
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+main() { struct in_addr ip; ip.s_addr = 0x12345678;
+if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
+    strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
+exit(1);}],
+           libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)])
+if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then
+    AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
+fi
index e0cc57f4c80c6cd340ae63d5dd9872516683d29b..8e17258918bd30b957e040f1766e375db8d6b5a5 100644 (file)
@@ -120,24 +120,6 @@ if test x"$libreplace_cv_USABLE_NET_IF_H" = x"yes";then
        AC_DEFINE(HAVE_NET_IF_H, 1, usability of net/if.h)
 fi
 
-AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[
-AC_TRY_RUN([
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-main() { struct in_addr ip; ip.s_addr = 0x12345678;
-if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
-    strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } 
-exit(1);}],
-           libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)])
-if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then
-    AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced])
-fi
-
 AC_HAVE_TYPE([socklen_t],[#include <sys/socket.h>])
 AC_HAVE_TYPE([sa_family_t],[#include <sys/socket.h>])
 AC_HAVE_TYPE([struct addrinfo], [#include <netdb.h>])
@@ -176,7 +158,7 @@ fi
 AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
 AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
 AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup)
-AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair)
+AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp)
 AC_CHECK_FUNCS(isatty)
 AC_HAVE_DECL(setresuid, [#include <unistd.h>])
 AC_HAVE_DECL(setresgid, [#include <unistd.h>])
@@ -347,9 +329,12 @@ m4_include(timegm.m4)
 m4_include(socket.m4)
 m4_include(inet_ntop.m4)
 m4_include(inet_pton.m4)
+m4_include(inet_aton.m4)
+m4_include(inet_ntoa.m4)
 m4_include(getaddrinfo.m4)
 m4_include(repdir.m4)
 m4_include(getifaddrs.m4)
+m4_include(socketpair.m4)
 
 AC_CHECK_FUNCS([syslog printf memset memcpy],,[AC_MSG_ERROR([Required function not found])])
 
index b2a240e8ab4ad2c70eb30d94741dc2ee2bb84bbc..6930f9b0791c057deeb8045be91b085d25f662ff 100644 (file)
@@ -27,7 +27,6 @@
 #include "system/time.h"
 #include "system/passwd.h"
 #include "system/syslog.h"
-#include "system/network.h"
 #include "system/locale.h"
 #include "system/wait.h"
 
@@ -295,20 +294,6 @@ char *rep_strdup(const char *s)
 }
 #endif /* HAVE_STRDUP */
 
-#ifndef WITH_PTHREADS
-/* REWRITE: not thread safe */
-#ifdef REPLACE_INET_NTOA
-char *rep_inet_ntoa(struct in_addr ip)
-{
-       uint8_t *p = (uint8_t *)&ip.s_addr;
-       static char buf[18];
-       slprintf(buf, 17, "%d.%d.%d.%d", 
-                (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
-       return buf;
-}
-#endif /* REPLACE_INET_NTOA */
-#endif
-
 #ifndef HAVE_SETLINEBUF
 void rep_setlinebuf(FILE *stream)
 {
@@ -599,25 +584,3 @@ int rep_unsetenv(const char *name)
        return 0;
 }
 #endif
-
-#ifndef HAVE_SOCKETPAIR
-int rep_socketpair(int d, int type, int protocol, int sv[2])
-{
-       if (d != AF_UNIX) {
-               errno = EAFNOSUPPORT;
-               return -1;
-       }
-
-       if (protocol != 0) {
-               errno = EPROTONOSUPPORT;
-               return -1;
-       }
-
-       if (type != SOCK_STREAM) {
-               errno = EOPNOTSUPP;
-               return -1;
-       }
-
-       return pipe(sv);
-}
-#endif
index 0d16f4ffd0a797ad6f959eb07612a6419a1b698b..5fe79394ebf63fd4bb1d7bfeb96e9a163e38cfed 100644 (file)
@@ -212,7 +212,7 @@ int rep_dlclose(void *handle);
 
 #ifndef HAVE_SOCKETPAIR
 #define socketpair rep_socketpair
-int rep_socketpair(int d, int type, int protocol, int sv[2]);
+/* prototype is in system/network.h */
 #endif
 
 #ifndef PRINTF_ATTRIBUTE
@@ -325,7 +325,7 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset);
 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset);
 #endif
 
-#ifdef REPLACE_INET_NTOA
+#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA)
 #define inet_ntoa rep_inet_ntoa
 /* prototype is in "system/network.h" */
 #endif
@@ -340,6 +340,11 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
 /* prototype is in "system/network.h" */
 #endif
 
+#ifndef HAVE_INET_ATON
+#define inet_aton rep_inet_aton
+/* prototype is in "system/network.h" */
+#endif
+
 #ifndef HAVE_CONNECT
 #define connect rep_connect
 /* prototype is in "system/network.h" */
index a2e04f53b1d7f006240a621065701d8224a57d36..e62c3d3cd1740f435936c4ecb95852aa9443c6e6 100644 (file)
@@ -3,6 +3,9 @@ AC_LIBREPLACE_BROKEN_CHECKS
 SMB_EXT_LIB(LIBREPLACE_EXT, [${LIBDL}])
 SMB_ENABLE(LIBREPLACE_EXT)
 
+SMB_EXT_LIB(LIBREPLACE_NETWORK, [${LIBREPLACE_NETWORK_LIBS}])
+SMB_ENABLE(LIBREPLACE_NETWORK)
+
 # remove leading ./
 LIBREPLACE_DIR=`echo ${libreplacedir} |sed -e 's/^\.\///g'`
 
index 9f8a7657e525b7653b7f6148441c83bc3255f6c5..a174dcffed765670a75e6a25d8e376cca521701d 100644 (file)
@@ -1264,7 +1264,7 @@ static int add_cnk_list_entry(struct pr_chunk_x **list,
        VA_COPY(ap2, ap);
        ret = vsnprintf(NULL, 0, format, ap2);
        va_end(ap2);
-       if (ret <= 0) return ret;
+       if (ret < 0) return ret;
 
        (*ptr) = (char *)malloc(ret+1);
        if (!*ptr) return -1;
index c0c8f93e81d79bd55fcc3b9dd53aec08a3f24095..984f81f15f364df3c1be9b23cf203e6dfa633a28 100644 (file)
@@ -7,10 +7,10 @@ dnl only looks in /etc/hosts), so we only look for -lsocket if we need
 dnl it.
 AC_CHECK_FUNCS(connect)
 if test x"$ac_cv_func_connect" = x"no"; then
-       AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect)
-       AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect)
-       AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect)
-       AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect)
+       AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, connect)
+       AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, connect)
+       AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, connect)
+       AC_CHECK_LIB_EXT(inet, LIBREPLACE_NETWORK_LIBS, connect)
        dnl We can't just call AC_CHECK_FUNCS(connect) here,
        dnl because the value has been cached.
        if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" ||
@@ -24,9 +24,9 @@ fi
 
 AC_CHECK_FUNCS(gethostbyname)
 if test x"$ac_cv_func_gethostbyname" = x"no"; then
-       AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname)
-       AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname)
-       AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname)
+       AC_CHECK_LIB_EXT(nsl_s, LIBREPLACE_NETWORK_LIBS, gethostbyname)
+       AC_CHECK_LIB_EXT(nsl, LIBREPLACE_NETWORK_LIBS, gethostbyname)
+       AC_CHECK_LIB_EXT(socket, LIBREPLACE_NETWORK_LIBS, gethostbyname)
        dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here,
        dnl because the value has been cached.
        if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" ||
@@ -37,4 +37,3 @@ if test x"$ac_cv_func_gethostbyname" = x"no"; then
                          [Whether the system has gethostbyname()])
        fi
 fi
-
diff --git a/source/lib/replace/socketpair.c b/source/lib/replace/socketpair.c
new file mode 100644 (file)
index 0000000..c775730
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * replacement routines for broken systems
+ * Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2006
+ * Copyright (C) Michael Adam <obnox@samba.org> 2008
+ *
+ *  ** NOTE! The following LGPL license applies to the replace
+ *  ** library. This does NOT imply that all of Samba is released
+ *  ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/network.h"
+
+int rep_socketpair(int d, int type, int protocol, int sv[2])
+{
+       if (d != AF_UNIX) {
+               errno = EAFNOSUPPORT;
+               return -1;
+       }
+
+       if (protocol != 0) {
+               errno = EPROTONOSUPPORT;
+               return -1;
+       }
+
+       if (type != SOCK_STREAM) {
+               errno = EOPNOTSUPP;
+               return -1;
+       }
+
+       return pipe(sv);
+}
diff --git a/source/lib/replace/socketpair.m4 b/source/lib/replace/socketpair.m4
new file mode 100644 (file)
index 0000000..7088334
--- /dev/null
@@ -0,0 +1 @@
+AC_CHECK_FUNCS(socketpair,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} socketpair.o"])
index 410c6d7cca2904d12e738c470cc90a6cc581a5ac..a5fb813aa15b3e4fd2689c7d9769b3196b4e13b3 100644 (file)
@@ -88,7 +88,7 @@
 typedef int socklen_t;
 #endif
 
-#ifdef REPLACE_INET_NTOA
+#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA)
 /* define is in "replace.h" */
 char *rep_inet_ntoa(struct in_addr ip);
 #endif
@@ -103,6 +103,11 @@ int rep_inet_pton(int af, const char *src, void *dst);
 const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size);
 #endif
 
+#ifndef HAVE_INET_ATON
+/* define is in "replace.h" */
+int rep_inet_aton(const char *src, struct in_addr *dst);
+#endif
+
 #ifndef HAVE_CONNECT
 /* define is in "replace.h" */
 int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
@@ -138,6 +143,11 @@ int rep_getifaddrs(struct ifaddrs **);
 void rep_freeifaddrs(struct ifaddrs *);
 #endif
 
+#ifndef HAVE_SOCKETPAIR
+/* define is in "replace.h" */
+int rep_socketpair(int d, int type, int protocol, int sv[2]);
+#endif
+
 /*
  * Some systems have getaddrinfo but not the
  * defines needed to use it.
@@ -305,7 +315,7 @@ struct addrinfo {
 
 /* Needed for some systems that don't define it (Solaris). */
 #ifndef ifr_netmask
-#define ifr_netmask ifr_addrs
+#define ifr_netmask ifr_addr
 #endif
 
 #ifdef SOCKET_WRAPPER
index a713090c6da2450b732696a8e99efb75f9637526..b40002b32114c699e8392c8a0c104f469b28c6f7 100644 (file)
@@ -11,50 +11,6 @@ if test x"$samba_cv_HAVE_SOCK_SIN_LEN" = x"yes"; then
     AC_DEFINE(HAVE_SOCK_SIN_LEN,1,[Whether the sockaddr_in struct has a sin_len property])
 fi
 
-# The following test taken from the cvs sources
-# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
-# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
-# libsocket.so which has a bad implementation of gethostbyname (it
-# only looks in /etc/hosts), so we only look for -lsocket if we need
-# it.
-AC_CHECK_FUNCS(connect)
-if test x"$ac_cv_func_connect" = x"no"; then
-    AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect)
-    AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect)
-    AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect)
-    AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect)
-    SMB_ENABLE(EXT_SOCKET,YES)
-    dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
-    dnl has been cached.
-    if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" ||
-       test x"$ac_cv_lib_ext_nsl_connect" = x"yes" ||
-       test x"$ac_cv_lib_ext_socket_connect" = x"yes" ||
-       test x"$ac_cv_lib_ext_inet_connect" = x"yes"; then
-        AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()])
-    else
-       AC_MSG_ERROR([no connect() function available!])
-    fi
-fi
-
-SMB_EXT_LIB(EXT_SOCKET,[${SOCKET_LIBS}],[${SOCKET_CFLAGS}],[${SOCKET_CPPFLAGS}],[${SOCKET_LDFLAGS}])
-
-AC_CHECK_FUNCS(gethostbyname)
-if test x"$ac_cv_func_gethostbyname" = x"no"; then
-    AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname)
-    AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname)
-    AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname)
-    SMB_ENABLE(EXT_NSL,YES)
-    dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, because the value
-    dnl has been cached.
-    if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" != x"yes" &&
-       test x"$ac_cv_lib_ext_nsl_gethostbyname" != x"yes" &&
-       test x"$ac_cv_lib_ext_socket_gethostbyname" != x"yes"; then
-               AC_MSG_ERROR([no gethostbyname() function available!])
-    fi
-fi
-
-SMB_EXT_LIB(EXT_NSL,[${NSL_LIBS}],[],[],[])
-
 ############################################
 # check for unix domain sockets
 AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [
index 5a7a62d8aeeaaeb22715b4722af55bfe93a0814f..777882f6e06930540cd95f14eaf542f9824a9200 100644 (file)
@@ -5,7 +5,7 @@ PRIVATE_PROTO_HEADER = netif_proto.h
 OBJ_FILES = \
                interface.o \
                netif.o
-PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBREPLACE_NETWORK
 # End SUBSYSTEM LIBNETIF
 ##############################
 
@@ -16,7 +16,7 @@ SUBSYSTEM = samba-socket
 OUTPUT_TYPE = MERGED_OBJ
 OBJ_FILES = \
                socket_ip.o
-PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL LIBSAMBA-ERRORS 
+PRIVATE_DEPENDENCIES = LIBSAMBA-ERRORS LIBREPLACE_NETWORK
 # End MODULE socket_ip
 ################################################
 
@@ -27,7 +27,7 @@ SUBSYSTEM = samba-socket
 OUTPUT_TYPE = MERGED_OBJ
 OBJ_FILES = \
                socket_unix.o
-PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
 # End MODULE socket_unix
 ################################################
 
index cc52a998015610ddbd1dc7c87259ac7ac0f7b0f0..2b9f30a7bbce16dcedf380cf77a0e695aff74063 100644 (file)
@@ -2,7 +2,7 @@
 # Start SUBSYSTEM SOCKET_WRAPPER
 [SUBSYSTEM::SOCKET_WRAPPER]
 OBJ_FILES = socket_wrapper.o
-PRIVATE_DEPENDENCIES = EXT_SOCKET
+PRIVATE_DEPENDENCIES = LIBREPLACE_NETWORK
 # End SUBSYSTEM SOCKET_WRAPPER
 ##############################
 
index 644365a66599d77362f6c6f7c2eb2783772a4bdf..86d9f7a312d57c56f42c0570e057772492c602fe 100644 (file)
@@ -64,6 +64,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <stdio.h>
+#include <stdint.h>
 
 #endif
 
@@ -624,67 +625,67 @@ enum swrap_packet_type {
 };
 
 struct swrap_file_hdr {
-       unsigned long   magic;
-       unsigned short  version_major;  
-       unsigned short  version_minor;
-       long            timezone;
-       unsigned long   sigfigs;
-       unsigned long   frame_max_len;
+       uint32_t        magic;
+       uint16_t        version_major;
+       uint16_t        version_minor;
+       int32_t         timezone;
+       uint32_t        sigfigs;
+       uint32_t        frame_max_len;
 #define SWRAP_FRAME_LENGTH_MAX 0xFFFF
-       unsigned long   link_type;
+       uint32_t        link_type;
 };
 #define SWRAP_FILE_HDR_SIZE 24
 
 struct swrap_packet {
        struct {
-               unsigned long seconds;
-               unsigned long micro_seconds;
-               unsigned long recorded_length;
-               unsigned long full_length;
+               uint32_t seconds;
+               uint32_t micro_seconds;
+               uint32_t recorded_length;
+               uint32_t full_length;
        } frame;
 #define SWRAP_PACKET__FRAME_SIZE 16
 
        struct {
                struct {
-                       unsigned char   ver_hdrlen;
-                       unsigned char   tos;
-                       unsigned short  packet_length;
-                       unsigned short  identification;
-                       unsigned char   flags;
-                       unsigned char   fragment;
-                       unsigned char   ttl;
-                       unsigned char   protocol;
-                       unsigned short  hdr_checksum;
-                       unsigned long   src_addr;
-                       unsigned long   dest_addr;
+                       uint8_t         ver_hdrlen;
+                       uint8_t         tos;
+                       uint16_t        packet_length;
+                       uint16_t        identification;
+                       uint8_t         flags;
+                       uint8_t         fragment;
+                       uint8_t         ttl;
+                       uint8_t         protocol;
+                       uint16_t        hdr_checksum;
+                       uint32_t        src_addr;
+                       uint32_t        dest_addr;
                } hdr;
 #define SWRAP_PACKET__IP_HDR_SIZE 20
 
                union {
                        struct {
-                               unsigned short  source_port;
-                               unsigned short  dest_port;
-                               unsigned long   seq_num;
-                               unsigned long   ack_num;
-                               unsigned char   hdr_length;
-                               unsigned char   control;
-                               unsigned short  window;
-                               unsigned short  checksum;
-                               unsigned short  urg;
+                               uint16_t        source_port;
+                               uint16_t        dest_port;
+                               uint32_t        seq_num;
+                               uint32_t        ack_num;
+                               uint8_t         hdr_length;
+                               uint8_t         control;
+                               uint16_t        window;
+                               uint16_t        checksum;
+                               uint16_t        urg;
                        } tcp;
 #define SWRAP_PACKET__IP_P_TCP_SIZE 20
                        struct {
-                               unsigned short  source_port;
-                               unsigned short  dest_port;
-                               unsigned short  length;
-                               unsigned short  checksum;
+                               uint16_t        source_port;
+                               uint16_t        dest_port;
+                               uint16_t        length;
+                               uint16_t        checksum;
                        } udp;
 #define SWRAP_PACKET__IP_P_UDP_SIZE 8
                        struct {
-                               unsigned char   type;
-                               unsigned char   code;
-                               unsigned short  checksum;
-                               unsigned long   unused;
+                               uint8_t         type;
+                               uint8_t         code;
+                               uint16_t        checksum;
+                               uint32_t        unused;
                        } icmp;
 #define SWRAP_PACKET__IP_P_ICMP_SIZE 8
                } p;
index 16a0357df83b8744560e604748bf64277bb7f064..22e6617f7cb0df2fb870bedd6bdc30269dea1271 100644 (file)
@@ -21,7 +21,7 @@ OBJ_FILES = xfile.o \
                become_daemon.o
 PUBLIC_DEPENDENCIES = \
                LIBTALLOC LIBCRYPTO \
-               SOCKET_WRAPPER EXT_NSL \
+               SOCKET_WRAPPER LIBREPLACE_NETWORK \
                CHARSET EXECINFO
 
 PUBLIC_HEADERS += $(addprefix lib/util/, util.h \
index 72118b23590a7c31568e6cbaffd9ee03a8750f83..eb9e4c45d98582487092e294a0198a15c834fb15 100644 (file)
@@ -3116,7 +3116,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_add(PyObject *SWIGUNUSEDPARM
   arg2 = (struct security_ace *)(argp2);
   result = security_descriptor_sacl_add(arg1,(struct security_ace const *)arg2);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3156,7 +3156,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_add(PyObject *SWIGUNUSEDPARM
   arg2 = (struct security_ace *)(argp2);
   result = security_descriptor_dacl_add(arg1,(struct security_ace const *)arg2);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3196,7 +3196,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_dacl_del(PyObject *SWIGUNUSEDPARM
   arg2 = (struct dom_sid *)(argp2);
   result = security_descriptor_dacl_del(arg1,(struct dom_sid const *)arg2);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3236,7 +3236,7 @@ SWIGINTERN PyObject *_wrap_security_descriptor_sacl_del(PyObject *SWIGUNUSEDPARM
   arg2 = (struct dom_sid *)(argp2);
   result = security_descriptor_sacl_del(arg1,(struct dom_sid const *)arg2);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
index f67e6dd0e3bf666bc86f3867abf6609b52a2cd00..e0bdb27cfc9563730bb9fc4533c4210b9fa0b54d 100644 (file)
@@ -4065,7 +4065,7 @@ SWIGINTERN PyObject *_wrap_do_nbt_name_query(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct nbt_name_query *)(argp3);
   result = do_nbt_name_query(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
index ede536a99579ebf0823b86b410a49c8a8b3ce59d..17efcbf62a8ca4e392b39b744c684c7ac14bdae2 100644 (file)
@@ -20,7 +20,7 @@
 #ifdef SWIGPYTHON
 %typemap(out,noblock=1) WERROR {
     if (!W_ERROR_IS_OK($1)) {
-        PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, win_errstr($1));
+        PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V($1), win_errstr($1));
         PyErr_SetObject(PyExc_RuntimeError, obj);
         SWIG_fail;
     } else if ($result == NULL) {
@@ -30,7 +30,7 @@
 
 %typemap(out,noblock=1) NTSTATUS {
     if (NT_STATUS_IS_ERR($1)) {
-        PyObject *obj = Py_BuildValue((char *)"(i,s)", $1.v, nt_errstr($1));
+        PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V($1), nt_errstr($1));
         PyErr_SetObject(PyExc_RuntimeError, obj);
         SWIG_fail;
     } else if ($result == NULL) {
index a4e27c151c753becfec7ba562ed102d0bf662813..29b30a87c2e4a92ca632284732d6b30680f9ed7c 100644 (file)
@@ -2679,7 +2679,7 @@ SWIGINTERN PyObject *_wrap_libnet_samsync_ldb(PyObject *SWIGUNUSEDPARM(self), Py
   arg3 = (struct libnet_samsync_ldb *)(argp3);
   result = libnet_samsync_ldb(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2721,7 +2721,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainList(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_DomainList *)(argp3);
   result = libnet_DomainList(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2763,7 +2763,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainClose(PyObject *SWIGUNUSEDPARM(self), Py
   arg3 = (struct libnet_DomainClose *)(argp3);
   result = libnet_DomainClose(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2805,7 +2805,7 @@ SWIGINTERN PyObject *_wrap_libnet_DomainOpen(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_DomainOpen *)(argp3);
   result = libnet_DomainOpen(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2847,7 +2847,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupName(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_LookupName *)(argp3);
   result = libnet_LookupName(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2889,7 +2889,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupDCs(PyObject *SWIGUNUSEDPARM(self), PyOb
   arg3 = (struct libnet_LookupDCs *)(argp3);
   result = libnet_LookupDCs(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2931,7 +2931,7 @@ SWIGINTERN PyObject *_wrap_libnet_LookupHost(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_Lookup *)(argp3);
   result = libnet_LookupHost(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -2973,7 +2973,7 @@ SWIGINTERN PyObject *_wrap_libnet_Lookup(PyObject *SWIGUNUSEDPARM(self), PyObjec
   arg3 = (struct libnet_Lookup *)(argp3);
   result = libnet_Lookup(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3015,7 +3015,7 @@ SWIGINTERN PyObject *_wrap_libnet_ListShares(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_ListShares *)(argp3);
   result = libnet_ListShares(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3057,7 +3057,7 @@ SWIGINTERN PyObject *_wrap_libnet_AddShare(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_AddShare *)(argp3);
   result = libnet_AddShare(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3099,7 +3099,7 @@ SWIGINTERN PyObject *_wrap_libnet_DelShare(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_DelShare *)(argp3);
   result = libnet_DelShare(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3141,7 +3141,7 @@ SWIGINTERN PyObject *_wrap_libnet_GroupList(PyObject *SWIGUNUSEDPARM(self), PyOb
   arg3 = (struct libnet_GroupList *)(argp3);
   result = libnet_GroupList(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3183,7 +3183,7 @@ SWIGINTERN PyObject *_wrap_libnet_GroupInfo(PyObject *SWIGUNUSEDPARM(self), PyOb
   arg3 = (struct libnet_GroupInfo *)(argp3);
   result = libnet_GroupInfo(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3225,7 +3225,7 @@ SWIGINTERN PyObject *_wrap_libnet_UserList(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_UserList *)(argp3);
   result = libnet_UserList(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3267,7 +3267,7 @@ SWIGINTERN PyObject *_wrap_libnet_UserInfo(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_UserInfo *)(argp3);
   result = libnet_UserInfo(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3309,7 +3309,7 @@ SWIGINTERN PyObject *_wrap_libnet_ModifyUser(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_ModifyUser *)(argp3);
   result = libnet_ModifyUser(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3351,7 +3351,7 @@ SWIGINTERN PyObject *_wrap_libnet_DeleteUser(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_DeleteUser *)(argp3);
   result = libnet_DeleteUser(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3393,7 +3393,7 @@ SWIGINTERN PyObject *_wrap_libnet_CreateUser(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_CreateUser *)(argp3);
   result = libnet_CreateUser(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3435,7 +3435,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamDump_keytab(PyObject *SWIGUNUSEDPARM(self),
   arg3 = (struct libnet_SamDump_keytab *)(argp3);
   result = libnet_SamDump_keytab(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3477,7 +3477,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamDump(PyObject *SWIGUNUSEDPARM(self), PyObje
   arg3 = (struct libnet_SamDump *)(argp3);
   result = libnet_SamDump(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3519,7 +3519,7 @@ SWIGINTERN PyObject *_wrap_libnet_SamSync_netlogon(PyObject *SWIGUNUSEDPARM(self
   arg3 = (struct libnet_SamSync *)(argp3);
   result = libnet_SamSync_netlogon(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3561,7 +3561,7 @@ SWIGINTERN PyObject *_wrap_libnet_UnbecomeDC(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_UnbecomeDC *)(argp3);
   result = libnet_UnbecomeDC(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3603,7 +3603,7 @@ SWIGINTERN PyObject *_wrap_libnet_BecomeDC(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_BecomeDC *)(argp3);
   result = libnet_BecomeDC(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3652,7 +3652,7 @@ SWIGINTERN PyObject *_wrap_libnet_JoinSite(PyObject *SWIGUNUSEDPARM(self), PyObj
   arg3 = (struct libnet_JoinDomain *)(argp3);
   result = libnet_JoinSite(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3694,7 +3694,7 @@ SWIGINTERN PyObject *_wrap_libnet_JoinDomain(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_JoinDomain *)(argp3);
   result = libnet_JoinDomain(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3736,7 +3736,7 @@ SWIGINTERN PyObject *_wrap_libnet_Join(PyObject *SWIGUNUSEDPARM(self), PyObject
   arg3 = (struct libnet_Join *)(argp3);
   result = libnet_Join(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3778,7 +3778,7 @@ SWIGINTERN PyObject *_wrap_libnet_RpcConnect(PyObject *SWIGUNUSEDPARM(self), PyO
   arg3 = (struct libnet_RpcConnect *)(argp3);
   result = libnet_RpcConnect(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3820,7 +3820,7 @@ SWIGINTERN PyObject *_wrap_libnet_RemoteTOD(PyObject *SWIGUNUSEDPARM(self), PyOb
   arg3 = (union libnet_RemoteTOD *)(argp3);
   result = libnet_RemoteTOD(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3862,7 +3862,7 @@ SWIGINTERN PyObject *_wrap_libnet_ChangePassword(PyObject *SWIGUNUSEDPARM(self),
   arg3 = (union libnet_ChangePassword *)(argp3);
   result = libnet_ChangePassword(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
@@ -3904,7 +3904,7 @@ SWIGINTERN PyObject *_wrap_libnet_SetPassword(PyObject *SWIGUNUSEDPARM(self), Py
   arg3 = (union libnet_SetPassword *)(argp3);
   result = libnet_SetPassword(arg1,arg2,arg3);
   if (NT_STATUS_IS_ERR(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, nt_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", NT_STATUS_V(result), nt_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
index 7abc693960e6369055ff18424603b5ccb285c3ae..a316e059b3da8f01f9cbbb0ea2e6fc04f0e790ff 100644 (file)
@@ -10,7 +10,7 @@ OBJ_FILES = \
                ndr/ndr_basic.o \
                ndr/ndr_string.o \
                ndr/uuid.o
-PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET EXT_NSL \
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET \
                                          LIBSAMBA-CONFIG
 # End SUBSYSTEM LIBNDR
 ################################################
index 1399f120a7c7e902b3b04f18901bc4824bb97eae..6e77cb7c756d9f64790f5338935bd82442d4aab5 100644 (file)
@@ -881,8 +881,6 @@ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs,
 
        talloc_steal(r, wait_handle);
 
-       talloc_steal(pvfs, r);
-
        return NT_STATUS_OK;
 }
 
@@ -1371,6 +1369,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                return status;
        }
 
+       f->handle->have_opendb_entry = true;
+
        if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) {
                oplock_granted = OPLOCK_BATCH;
        } else if (oplock_granted != OPLOCK_NONE) {
@@ -1381,8 +1381,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                }
        }
 
-       f->handle->have_opendb_entry = true;
-
        stream_existed = name->stream_exists;
 
        /* if this was a stream create then create the stream as well */
index 7a2d964b9dd82d82a90f504c19b88d538458909b..4cb47a4f1fa330c4bb113909412e705c87dfa12a 100644 (file)
@@ -219,6 +219,12 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
                return pvfs_unlink_one(pvfs, req, unl, name);
        }
 
+       /*
+        * disable async requests in the wildcard case
+        * untill we have proper tests for this
+        */
+       req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;
+
        /* get list of matching files */
        status = pvfs_list_start(pvfs, name, req, &dir);
        if (!NT_STATUS_IS_OK(status)) {
index da03d83dbcae19aca02c882282ae9021ee349fd0..0aa4d65d8c5ca22973bbed19bfce099b25157c6e 100644 (file)
@@ -324,11 +324,11 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
        struct samr_connect_state *c_state;
        struct dcesrv_handle *h;
        struct samr_SamArray *array;
-       int count, i, start_i;
+       int i, start_i, ret;
        const char * const dom_attrs[] = { "cn", NULL};
        const char * const ref_attrs[] = { "nETBIOSName", NULL};
-       struct ldb_message **dom_msgs;
-       struct ldb_message **ref_msgs;
+       struct ldb_result *dom_res;
+       struct ldb_result *ref_res;
        struct ldb_dn *partitions_basedn;
 
        *r->out.resume_handle = 0;
@@ -341,19 +341,18 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
 
        partitions_basedn = samdb_partitions_dn(c_state->sam_ctx, mem_ctx);
 
-       count = gendb_search(c_state->sam_ctx,
-                            mem_ctx, NULL, &dom_msgs, dom_attrs,
-                            "(objectClass=domain)");
-       if (count == -1) {
-               DEBUG(0,("samdb: no domains found in EnumDomains\n"));
+       ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &dom_res, ldb_get_default_basedn(c_state->sam_ctx),
+                                LDB_SCOPE_SUBTREE, dom_attrs, "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
+       if (ret != LDB_SUCCESS) {
+               DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
 
-       *r->out.resume_handle = count;
+       *r->out.resume_handle = dom_res->count;
 
        start_i = *r->in.resume_handle;
 
-       if (start_i >= count) {
+       if (start_i >= dom_res->count) {
                /* search past end of list is not an error for this call */
                return NT_STATUS_OK;
        }
@@ -366,23 +365,27 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
        array->count = 0;
        array->entries = NULL;
 
-       array->entries = talloc_array(mem_ctx, struct samr_SamEntry, count - start_i);
+       array->entries = talloc_array(mem_ctx, struct samr_SamEntry, dom_res->count - start_i);
        if (array->entries == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       for (i=0;i<count-start_i;i++) {
-               int ret;
+       for (i=0;i<dom_res->count-start_i;i++) {
                array->entries[i].idx = start_i + i;
                /* try and find the domain */
-               ret = gendb_search(c_state->sam_ctx, mem_ctx, partitions_basedn,
-                                  &ref_msgs, ref_attrs, 
-                                  "(&(objectClass=crossRef)(ncName=%s))", 
-                                  ldb_dn_get_linearized(dom_msgs[i]->dn));
-               if (ret == 1) {
-                       array->entries[i].name.string = samdb_result_string(ref_msgs[0], "nETBIOSName", NULL);
+               ret = ldb_search_exp_fmt(c_state->sam_ctx, mem_ctx, &ref_res, partitions_basedn,
+                                        LDB_SCOPE_SUBTREE, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", 
+                                        ldb_dn_get_linearized(dom_res->msgs[i]->dn));
+
+               if (ret != LDB_SUCCESS) {
+                       DEBUG(0,("samdb: unable to find domains: %s\n", ldb_errstring(c_state->sam_ctx)));
+                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
+               }
+
+               if (ref_res->count == 1) {
+                       array->entries[i].name.string = samdb_result_string(ref_res->msgs[0], "nETBIOSName", NULL);
                } else {
-                       array->entries[i].name.string = samdb_result_string(dom_msgs[i], "cn", NULL);
+                       array->entries[i].name.string = samdb_result_string(dom_res->msgs[i], "cn", NULL);
                }
        }
 
@@ -472,6 +475,14 @@ static NTSTATUS dcesrv_samr_OpenDomain(struct dcesrv_call_state *dce_call, TALLO
        }
        d_state->access_mask = r->in.access_mask;
 
+       if (dom_sid_equal(d_state->domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+               d_state->builtin = true;
+       } else {
+               d_state->builtin = false;
+       }
+
+       d_state->lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+
        h_domain = dcesrv_handle_new(dce_call->context, SAMR_HANDLE_DOMAIN);
        if (!h_domain) {
                talloc_free(d_state);
@@ -520,6 +531,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo2(struct samr_domain_state *state,
           string */
        info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, dom_msgs[0], "fSMORoleOwner");
 
+       if (!info->primary.string) {
+               info->primary.string = lp_netbios_name(state->lp_ctx);
+       }
+
        info->force_logoff_time = ldb_msg_find_attr_as_uint64(dom_msgs[0], "forceLogoff", 
                                                            0x8000000000000000LL);
 
@@ -614,6 +629,10 @@ static NTSTATUS dcesrv_samr_info_DomInfo6(struct samr_domain_state *state,
        info->primary.string = samdb_result_fsmo_name(state->sam_ctx, mem_ctx, 
                                                      dom_msgs[0], "fSMORoleOwner");
 
+       if (!info->primary.string) {
+               info->primary.string = lp_netbios_name(state->lp_ctx);
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -1004,6 +1023,11 @@ static NTSTATUS dcesrv_samr_CreateDomainGroup(struct dcesrv_call_state *dce_call
 
        d_state = h->data;
 
+       if (d_state->builtin) {
+               DEBUG(5, ("Cannot create a domain group in the BUILTIN domain"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        groupname = r->in.name->string;
 
        if (groupname == NULL) {
@@ -1130,9 +1154,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
        if (ldb_cnt == -1) {
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
-       if (ldb_cnt == 0 || r->in.max_size == 0) {
-               return NT_STATUS_OK;
-       }
 
        /* convert to SamEntry format */
        entries = talloc_array(mem_ctx, struct samr_SamEntry, ldb_cnt);
@@ -1166,10 +1187,6 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
             first<count && entries[first].idx <= *r->in.resume_handle;
             first++) ;
 
-       if (first == count) {
-               return NT_STATUS_OK;
-       }
-
        /* return the rest, limit by max_size. Note that we 
           use the w2k3 element size value of 54 */
        r->out.num_entries = count - first;
@@ -1234,6 +1251,10 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
 
        d_state = h->data;
 
+       if (d_state->builtin) {
+               DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
        account_name = r->in.account_name->string;
 
        if (account_name == NULL) {
@@ -1318,15 +1339,16 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
        /* create the user */
        ret = ldb_add(d_state->sam_ctx, msg);
        switch (ret) {
-       case  LDB_SUCCESS:
+       case LDB_SUCCESS:
                break;
-       case  LDB_ERR_ENTRY_ALREADY_EXISTS:
+       case LDB_ERR_ENTRY_ALREADY_EXISTS:
                ldb_transaction_cancel(d_state->sam_ctx);
                DEBUG(0,("Failed to create user record %s: %s\n",
                         ldb_dn_get_linearized(msg->dn),
                         ldb_errstring(d_state->sam_ctx)));
                return NT_STATUS_USER_EXISTS;
-       case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
+       case LDB_ERR_UNWILLING_TO_PERFORM:
+       case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
                ldb_transaction_cancel(d_state->sam_ctx);
                DEBUG(0,("Failed to create user record %s: %s\n",
                         ldb_dn_get_linearized(msg->dn),
@@ -1466,8 +1488,8 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
 {
        struct dcesrv_handle *h;
        struct samr_domain_state *d_state;
-       struct ldb_message **res;
-       int count, num_filtered_entries, i, first;
+       struct ldb_result *res;
+       int ret, num_filtered_entries, i, first;
        struct samr_SamEntry *entries;
        const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
 
@@ -1479,32 +1501,30 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
 
        d_state = h->data;
        
-       /* search for all users in this domain. This could possibly be cached and 
-          resumed based on resume_key */
-       count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, 
-                            "objectclass=user");
-       if (count == -1) {
+       /* don't have to worry about users in the builtin domain, as there are none */
+       ret = ldb_search_exp_fmt(d_state->sam_ctx, mem_ctx, &res, d_state->domain_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=user");
+
+       if (ret != LDB_SUCCESS) {
+               DEBUG(3, ("Failed to search for Domain Users in %s: %s\n", 
+                         ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(d_state->sam_ctx)));
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
-       if (count == 0 || r->in.max_size == 0) {
-               return NT_STATUS_OK;
-       }
 
        /* convert to SamEntry format */
-       entries = talloc_array(mem_ctx, struct samr_SamEntry, count);
+       entries = talloc_array(mem_ctx, struct samr_SamEntry, res->count);
        if (!entries) {
                return NT_STATUS_NO_MEMORY;
        }
        num_filtered_entries = 0;
-       for (i=0;i<count;i++) {
+       for (i=0;i<res->count;i++) {
                /* Check if a mask has been requested */
                if (r->in.acct_flags
-                   && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res[i], 
+                   && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, res->msgs[i], 
                                                 d_state->domain_dn) & r->in.acct_flags) == 0)) {
                        continue;
                }
-               entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
-               entries[num_filtered_entries].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+               entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res->msgs[i], "objectSid", 0);
+               entries[num_filtered_entries].name.string = samdb_result_string(res->msgs[i], "sAMAccountName", "");
                num_filtered_entries++;
        }
 
@@ -1566,6 +1586,11 @@ static NTSTATUS dcesrv_samr_CreateDomAlias(struct dcesrv_call_state *dce_call, T
 
        d_state = h->data;
 
+       if (d_state->builtin) {
+               DEBUG(5, ("Cannot create a domain alias in the BUILTIN domain"));
+               return NT_STATUS_ACCESS_DENIED;
+       }
+
        alias_name = r->in.alias_name->string;
 
        if (alias_name == NULL) {
@@ -2073,7 +2098,8 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
 {
        struct dcesrv_handle *h;
        struct samr_account_state *a_state;
-       struct ldb_message *msg, **res;
+       struct ldb_message *msg;
+       struct ldb_result *res;
        const char * const attrs[4] = { "sAMAccountName", "description",
                                        "numMembers", NULL };
        int ret;
@@ -2083,14 +2109,22 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
        DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
 
        a_state = h->data;
+       
+       ret = ldb_search_exp_fmt(a_state->sam_ctx, mem_ctx, &res, a_state->account_dn, LDB_SCOPE_SUBTREE, attrs, "objectClass=*");
+       
+       if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+               return NT_STATUS_NO_SUCH_GROUP;
+       } else if (ret != LDB_SUCCESS) {
+               DEBUG(2, ("Error reading group info: %s\n", ldb_errstring(a_state->sam_ctx)));
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
 
-       /* pull all the group attributes */
-       ret = gendb_search_dn(a_state->sam_ctx, mem_ctx,
-                             a_state->account_dn, &res, attrs);
-       if (ret != 1) {
+       if (res->count != 1) {
+               DEBUG(2, ("Error finding group info, got %d entries\n", res->count));
+               
                return NT_STATUS_INTERNAL_DB_CORRUPTION;
        }
-       msg = res[0];
+       msg = res->msgs[0];
 
        /* allocate the info structure */
        r->out.info = talloc(mem_ctx, union samr_GroupInfo);
index 7a6978344be852911ba2342771d8d6886f8e30a8..a28a4bec437ea88108261e7b245dea2ca079e21e 100644 (file)
@@ -52,6 +52,8 @@ struct samr_domain_state {
        const char *domain_name;
        struct ldb_dn *domain_dn;
        enum server_role role;
+       bool builtin;
+       struct loadparm_context *lp_ctx;
 };
 
 /*
index 45361c22b10e487c3a95ef3588640291776db2b9..5171d171a74b6ed277fc8878d3c7e88dfdfd092e 100755 (executable)
@@ -4,4 +4,6 @@ ENV="$1"
 
 shift 1
 
-$ENV valgrind -q --db-attach=yes --num-callers=30 $@
+CMD="$ENV valgrind -q --db-attach=yes --num-callers=30 $@"
+echo $CMD
+eval $CMD
index 2142cd9abd13c3cf1a5476fccf4521bf7579050d..aac98ebc60d13e8251d47a0ae11522ac6e488bc4 100644 (file)
@@ -22,6 +22,8 @@ AC_DEFUN([TRY_LINK_PYTHON],
                CFLAGS="$CFLAGS $2"
 
                AC_TRY_LINK([
+                               /* we have our own configure tests */
+                               #define Py_PYCONFIG_H 1
                                #include <Python.h>
                                #include <stdlib.h>
                        ],[
index a16d737344c9b45622e3870003da894a54cf625c..09c77813ca47d92b8ddfc3ac310465af0cbab298 100644 (file)
@@ -21,7 +21,7 @@ swig:: pythonmods
 .SUFFIXES: _wrap.c .i
 
 .i_wrap.c:
-       [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $<
+       [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $<
 
 realdistclean::
        @echo "Removing SWIG output files"
index f467f851bdd86138363b5d310398666afd210764..cf85e91e1e6bc61bcdef165b34e29bf0b11a41e9 100644 (file)
@@ -3027,7 +3027,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE
     "ldb context must be non-NULL");
   result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3);
   if (!W_ERROR_IS_OK(result)) {
-    PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result));
+    PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result));
     PyErr_SetObject(PyExc_RuntimeError, obj);
     SWIG_fail;
   } else if (resultobj == NULL) {
index 25316e888a2e96882df64b336d45348ed125241f..47d00f8871c39d984c4d8b3bea896cb936f4a6fb 100644 (file)
@@ -1173,27 +1173,10 @@ def provision_backend(setup_dir=None, message=None,
         mapping = "schema-map-fedora-ds-1.0"
         backend_schema = "99_ad.ldif"
     elif ldap_backend_type == "openldap":
-        setup_file(setup_path("slapd.conf"), paths.slapdconf,
-                   {"DNSDOMAIN": names.dnsdomain,
-                    "LDAPDIR": paths.ldapdir,
-                    "DOMAINDN": names.domaindn,
-                    "CONFIGDN": names.configdn,
-                    "SCHEMADN": names.schemadn,
-                    "LDAPMANAGERDN": names.ldapmanagerdn,
-                    "LDAPMANAGERPASS": adminpass})
-        setup_file(setup_path("modules.conf"), paths.modulesconf,
-                   {"REALM": names.realm})
-        
-        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user"))
-        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config"))
-        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema"))
-        mapping = "schema-map-openldap-2.3"
-        backend_schema = "backend-schema.schema"
-        
         attrs = ["linkID", "lDAPDisplayName"]
        res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs);
 
-       memberof_config = "# This is a generated file, do not edit!\n";
+       memberof_config = "# Generated from schema in " + schemadb_path + "\n";
        refint_attributes = "";
        for i in range (0, len(res)):
             linkid = res[i]["linkID"][0]
@@ -1219,10 +1202,24 @@ memberof-dangling-error 32
 overlay refint
 refint_attributes""" + refint_attributes + "\n";
        
-        if os.path.exists(paths.memberofconf):
-            os.unlink(paths.memberof.conf)
-
-        open(paths.memberofconf, 'w').write(memberof_config)
+        setup_file(setup_path("slapd.conf"), paths.slapdconf,
+                   {"DNSDOMAIN": names.dnsdomain,
+                    "LDAPDIR": paths.ldapdir,
+                    "DOMAINDN": names.domaindn,
+                    "CONFIGDN": names.configdn,
+                    "SCHEMADN": names.schemadn,
+                    "LDAPMANAGERDN": names.ldapmanagerdn,
+                    "LDAPMANAGERPASS": adminpass,
+                    "MEMBEROF_CONFIG": memberof_config})
+        setup_file(setup_path("modules.conf"), paths.modulesconf,
+                   {"REALM": names.realm})
+        
+        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user"))
+        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config"))
+        setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema"))
+        mapping = "schema-map-openldap-2.3"
+        backend_schema = "backend-schema.schema"
+        
 
         ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="")
         message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri)
index e491a999ab196e9fd09fc0ff5d6aa1a21c592098..25ff74792e518f01e0a010ab8b8d8fbbdb52419c 100644 (file)
@@ -7,8 +7,6 @@ use Exporter;
 use FindBin qw($RealBin);
 use lib "$RealBin/..";
 
-use Subunit qw(parse_results);
-
 use strict;
 
 sub new($$$$$$$) {
@@ -62,7 +60,9 @@ sub output_msg($$)
        my ($self, $output) = @_;
 
        if ($self->{verbose}) {
+               require FileHandle;
                print $output;
+               STDOUT->flush();
        } else {
                $self->{test_output}->{$self->{NAME}} .= $output;
        }
index 73d03f3d4ca57e0e9d05c76d8b7bcaf80c23ef86..39a1b5a45089be203d4da12aa4dd4730f3a0b6b6 100755 (executable)
@@ -584,7 +584,7 @@ push (@torture_options, "--configfile=$conffile");
 push (@torture_options, "--maximum-runtime=$torture_maxtime");
 push (@torture_options, "--target=$opt_target");
 push (@torture_options, "--basedir=$prefix_abs");
-push (@torture_options, "--option=torture:progress=no") if ($opt_format eq "buildfarm");
+push (@torture_options, "--option=torture:progress=no") unless ($opt_verbose);
 push (@torture_options, "--format=subunit");
 push (@torture_options, "--option=torture:quick=yes") if ($opt_quick);
 
index 83f4da335901daf6055463186860e2bd5b927a41..cdf9ff79a98ae40f60c30b1582a26f53587a1cbf 100644 (file)
@@ -21,7 +21,7 @@ include ${LDAPDIR}/modules.conf
 
 defaultsearchbase ${DOMAINDN}
 
-include ${LDAPDIR}/memberof.conf
+${MEMBEROF_CONFIG}
 
 database        hdb
 suffix         ${SCHEMADN}
@@ -62,8 +62,6 @@ syncprov-sessionlog 100
 
 database        hdb
 suffix         ${DOMAINDN}
-rootdn          ${LDAPMANAGERDN}
-rootpw          ${LDAPMANAGERPASS}
 directory      ${LDAPDIR}/db/user
 index           objectClass eq
 index           samAccountName eq
@@ -82,8 +80,12 @@ index dnsRoot eq
 index nETBIOSName eq
 index cn eq
 
+rootdn          ${LDAPMANAGERDN}
+rootpw          ${LDAPMANAGERPASS}
+
 #syncprov is stable in OpenLDAP 2.3, and available in 2.2.  
 #We only need this for the contextCSN attribute anyway....
 overlay syncprov
 syncprov-checkpoint 100 10
 syncprov-sessionlog 100
+
index 1f86372aa37908b97d215dea4d2e34e336eb8add..ade41614c24329f74ce16c14798246f8e7e143da 100644 (file)
@@ -36,7 +36,8 @@ heimdal_basics: \
        heimdal/lib/krb5/krb_err.h \
        heimdal/lib/krb5/krb5_err.h \
        heimdal/lib/gssapi/gkrb5_err.h \
-       heimdal/lib/hx509/hx509_err.h
+       heimdal/lib/hx509/hx509_err.h \
+       heimdal/lib/wind/wind_err.h
 
 proto: basics
 basics: include/includes.h \
index 87b27d072837e42cd16e1b22b116adf96bcaf5a9..e8b2f5681354158c6b278e3384dbc91c9521c018 100644 (file)
@@ -37,7 +37,7 @@
 
 static int nprocs;
 static int open_failed;
-static int open_retries;
+static int close_failed;
 static char **fnames;
 static int num_connected;
 static struct timed_event *report_te;
@@ -49,12 +49,16 @@ struct benchopen_state {
        struct smbcli_state *cli;
        struct smbcli_tree *tree;
        int client_num;
-       int old_fnum;
-       int fnum;
-       int file_num;
+       int close_fnum;
+       int open_fnum;
+       int close_file_num;
+       int open_file_num;
+       int pending_file_num;
+       int next_file_num;
        int count;
        int lastcount;
        union smb_open open_parms;
+       int open_retries;
        union smb_close close_parms;
        struct smbcli_request *req_open;
        struct smbcli_request *req_close;
@@ -95,11 +99,11 @@ static void reopen_connection_complete(struct composite_context *ctx)
 
        num_connected++;
 
-       DEBUG(0,("reconnect to %s finished (%u connected)\n", state->dest_host,
-                num_connected));
+       DEBUG(0,("[%u] reconnect to %s finished (%u connected)\n",
+                state->client_num, state->dest_host, num_connected));
 
-       state->fnum = -1;
-       state->old_fnum = -1;
+       state->open_fnum = -1;
+       state->close_fnum = -1;
        next_open(state);
 }
 
@@ -136,7 +140,8 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te,
        /* kill off the remnants of the old connection */
        talloc_free(state->tree);
        state->tree = NULL;
-       state->fnum = -1;
+       state->open_fnum = -1;
+       state->close_fnum = -1;
 
        ctx = smb_composite_connect_send(io, state->mem_ctx, 
                                         lp_resolve_context(state->tctx->lp_ctx), 
@@ -158,9 +163,10 @@ static void next_open(struct benchopen_state *state)
 {
        state->count++;
 
-       state->file_num = (state->file_num+1) % (3*nprocs);
+       state->pending_file_num = state->next_file_num;
+       state->next_file_num = (state->next_file_num+1) % (3*nprocs);
 
-       DEBUG(2,("[%d] opening %u\n", state->client_num, state->file_num));
+       DEBUG(2,("[%d] opening %u\n", state->client_num, state->pending_file_num));
        state->open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX;
        state->open_parms.ntcreatex.in.flags = 0;
        state->open_parms.ntcreatex.in.root_fid = 0;
@@ -172,7 +178,7 @@ static void next_open(struct benchopen_state *state)
        state->open_parms.ntcreatex.in.create_options = 0;
        state->open_parms.ntcreatex.in.impersonation = 0;
        state->open_parms.ntcreatex.in.security_flags = 0;
-       state->open_parms.ntcreatex.in.fname = fnames[state->file_num];
+       state->open_parms.ntcreatex.in.fname = fnames[state->pending_file_num];
 
        state->req_open = smb_raw_open_send(state->tree, &state->open_parms);
        state->req_open->async.fn = open_completed;
@@ -182,18 +188,18 @@ static void next_open(struct benchopen_state *state)
 
 static void next_close(struct benchopen_state *state)
 {
-       DEBUG(2,("[%d] closing %d\n", state->client_num, state->old_fnum));
-       if (state->old_fnum == -1) {
+       if (state->close_fnum == -1) {
                return;
        }
+       DEBUG(2,("[%d] closing %d (fnum[%d])\n",
+                state->client_num, state->close_file_num, state->close_fnum));
        state->close_parms.close.level = RAW_CLOSE_CLOSE;
-       state->close_parms.close.in.file.fnum = state->old_fnum;
+       state->close_parms.close.in.file.fnum = state->close_fnum;
        state->close_parms.close.in.write_time = 0;
 
        state->req_close = smb_raw_close_send(state->tree, &state->close_parms);
        state->req_close->async.fn = close_completed;
        state->req_close->async.private = state;
-       state->old_fnum = -1;
 }
 
 /*
@@ -218,7 +224,8 @@ static void open_completed(struct smbcli_request *req)
                state->tree = NULL;
                state->cli = NULL;
                num_connected--;        
-               DEBUG(0,("reopening connection to %s\n", state->dest_host));
+               DEBUG(0,("[%u] reopening connection to %s\n",
+                        state->client_num, state->dest_host));
                talloc_free(state->te);
                state->te = event_add_timed(state->ev, state->mem_ctx, 
                                            timeval_current_ofs(1,0), 
@@ -227,8 +234,9 @@ static void open_completed(struct smbcli_request *req)
        }
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
-               DEBUG(2,("[%d] retrying open\n", state->client_num));
-               open_retries++;
+               DEBUG(2,("[%d] retrying open %d\n",
+                        state->client_num, state->pending_file_num));
+               state->open_retries++;
                state->req_open = smb_raw_open_send(state->tree, &state->open_parms);
                state->req_open->async.fn = open_completed;
                state->req_open->async.private = state;
@@ -237,17 +245,21 @@ static void open_completed(struct smbcli_request *req)
 
        if (!NT_STATUS_IS_OK(status)) {
                open_failed++;
-               DEBUG(0,("open failed - %s\n", nt_errstr(status)));
+               DEBUG(0,("[%u] open failed %d - %s\n",
+                        state->client_num, state->pending_file_num,
+                        nt_errstr(status)));
                return;
        }
 
-       state->old_fnum = state->fnum;
-       state->fnum = state->open_parms.ntcreatex.out.file.fnum;
+       state->close_file_num = state->open_file_num;
+       state->close_fnum = state->open_fnum;
+       state->open_file_num = state->pending_file_num;
+       state->open_fnum = state->open_parms.ntcreatex.out.file.fnum;
 
-       DEBUG(2,("[%d] open completed: fnum=%d old_fnum=%d\n", 
-                state->client_num, state->fnum, state->old_fnum));
+       DEBUG(2,("[%d] open completed %d (fnum[%d])\n",
+                state->client_num, state->open_file_num, state->open_fnum));
 
-       if (state->old_fnum != -1) {
+       if (state->close_fnum != -1) {
                next_close(state);
        }
 
@@ -271,7 +283,8 @@ static void close_completed(struct smbcli_request *req)
                state->tree = NULL;
                state->cli = NULL;
                num_connected--;        
-               DEBUG(0,("reopening connection to %s\n", state->dest_host));
+               DEBUG(0,("[%u] reopening connection to %s\n",
+                        state->client_num, state->dest_host));
                talloc_free(state->te);
                state->te = event_add_timed(state->ev, state->mem_ctx, 
                                            timeval_current_ofs(1,0), 
@@ -280,13 +293,17 @@ static void close_completed(struct smbcli_request *req)
        }
 
        if (!NT_STATUS_IS_OK(status)) {
-               open_failed++;
-               DEBUG(0,("close failed - %s\n", nt_errstr(status)));
+               close_failed++;
+               DEBUG(0,("[%u] close failed %d (fnum[%d]) - %s\n",
+                        state->client_num, state->close_file_num,
+                        state->close_fnum,
+                        nt_errstr(status)));
                return;
        }
 
-       DEBUG(2,("[%d] close completed: fnum=%d old_fnum=%d\n", 
-                state->client_num, state->fnum, state->old_fnum));
+       DEBUG(2,("[%d] close completed %d (fnum[%d])\n",
+                state->client_num, state->close_file_num,
+                state->close_fnum));
 }      
 
 static void echo_completion(struct smbcli_request *req)
@@ -298,7 +315,8 @@ static void echo_completion(struct smbcli_request *req)
                talloc_free(state->tree);
                state->tree = NULL;
                num_connected--;        
-               DEBUG(0,("reopening connection to %s\n", state->dest_host));
+               DEBUG(0,("[%u] reopening connection to %s\n",
+                        state->client_num, state->dest_host));
                talloc_free(state->te);
                state->te = event_add_timed(state->ev, state->mem_ctx, 
                                            timeval_current_ofs(1,0), 
@@ -352,7 +370,9 @@ bool torture_bench_open(struct torture_context *torture)
        struct timeval tv;
        struct event_context *ev = event_context_find(mem_ctx);
        struct benchopen_state *state;
-       int total = 0, minops=0;
+       int total = 0;
+       int total_retries = 0;
+       int minops = 0;
        bool progress=false;
 
        progress = torture_setting_bool(torture, "progress", true);
@@ -397,11 +417,10 @@ bool torture_bench_open(struct torture_context *torture)
        }
 
        for (i=0;i<nprocs;i++) {
-               state[i].file_num = i;          
-               state[i].fnum = smbcli_open(state[i].tree, 
-                                           fnames[state->file_num], 
-                                           O_RDWR|O_CREAT, DENY_ALL);
-               state[i].old_fnum = -1;
+               /* all connections start with the same file */
+               state[i].next_file_num = 0;
+               state[i].open_fnum = -1;
+               state[i].close_fnum = -1;
                next_open(&state[i]);
        }
 
@@ -420,17 +439,30 @@ bool torture_bench_open(struct torture_context *torture)
                        DEBUG(0,("open failed\n"));
                        goto failed;
                }
+               if (close_failed) {
+                       DEBUG(0,("open failed\n"));
+                       goto failed;
+               }
        }
 
        talloc_free(report_te);
+       if (progress) {
+               for (i=0;i<nprocs;i++) {
+                       printf("      ");
+               }
+               printf("\r");
+       }
 
-       printf("%.2f ops/second (%d retries)\n", 
-              total/timeval_elapsed(&tv), open_retries);
        minops = state[0].count;
        for (i=0;i<nprocs;i++) {
-               printf("[%d] %u ops\n", i, state[i].count);
+               total += state[i].count;
+               total_retries += state[i].open_retries;
+               printf("[%d] %u ops (%u retries)\n",
+                      i, state[i].count, state[i].open_retries);
                if (state[i].count < minops) minops = state[i].count;
        }
+       printf("%.2f ops/second (%d retries)\n",
+              total/timeval_elapsed(&tv), total_retries);
        if (minops < 0.5*total/nprocs) {
                printf("Failed: unbalanced open\n");
                goto failed;
index 5ab43d5e780aea9778fad048e5f2675e223f1b68..8b2e4fb17718f699559b0de5ec604a8d6b5374eb 100644 (file)
@@ -2539,7 +2539,7 @@ static bool test_raw_oplock_batch22(struct torture_context *tctx, struct smbcli_
        int te;
 
        if (torture_setting_bool(tctx, "samba3", false)) {
-               torture_skip(tctx, "BACHT22 disabled against samba3\n");
+               torture_skip(tctx, "BATCH22 disabled against samba3\n");
        }
 
        if (!torture_setup_dir(cli1, BASEDIR)) {
@@ -2629,7 +2629,7 @@ static bool test_raw_oplock_batch23(struct torture_context *tctx, struct smbcli_
        struct smbcli_state *cli3 = NULL;
 
        if (torture_setting_bool(tctx, "samba3", false)) {
-               torture_skip(tctx, "BACHT23 disabled against samba3\n");
+               torture_skip(tctx, "BATCH23 disabled against samba3\n");
        }
 
        if (!torture_setup_dir(cli1, BASEDIR)) {
index 60d022fbea77269019338f13beef7809240e5de4..04d13a97c1c51849bede4a85af95a75bbf040238 100644 (file)
@@ -295,8 +295,8 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p,
        ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
 
        name.name.string = "BUILTIN\\Administrators";
-       ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
        name.sid_type = SID_NAME_ALIAS;
+       ret &= test_LookupNames(p, mem_ctx, handle, &tnames);
 
        name.name.string = "SYSTEM";
        name.sid_type = SID_NAME_WKN_GRP;
index 1d6ec4339987e3cd0fb60e828efa35f67df2649f..55c75ba270eb415cc0227e8986516ea18e32fbcc 100644 (file)
@@ -2332,9 +2332,15 @@ static bool test_CreateAlias(struct dcerpc_pipe *p, struct torture_context *tctx
 
        status = dcerpc_samr_CreateDomAlias(p, tctx, &r);
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("Server refused create of '%s'\n", r.in.alias_name->string);
-               return true;
+       if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       printf("Server correctly refused create of '%s'\n", r.in.alias_name->string);
+                       return true;
+               } else {
+                       printf("Server should have refused create of '%s', got %s instead\n", r.in.alias_name->string, 
+                              nt_errstr(status));
+                       return false;
+               }
        }
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_ALIAS_EXISTS)) {
@@ -2515,7 +2521,8 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
 static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
                            struct policy_handle *domain_handle, 
-                           struct policy_handle *user_handle_out, 
+                           struct policy_handle *user_handle_out,
+                           struct dom_sid *domain_sid, 
                            enum torture_samr_choice which_ops)
 {
 
@@ -2546,10 +2553,15 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
 
        status = dcerpc_samr_CreateUser(p, user_ctx, &r);
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("Server refused create of '%s': %s\n", r.in.account_name->string, nt_errstr(status));
-               talloc_free(user_ctx);
-               return true;
+       if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
+                       return true;
+               } else {
+                       printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
+                              nt_errstr(status));
+                       return false;
+               }
        }
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
@@ -2610,7 +2622,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
 
 
 static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx,
-                            struct policy_handle *domain_handle, enum torture_samr_choice which_ops)
+                            struct policy_handle *domain_handle,
+                            struct dom_sid *domain_sid,
+                            enum torture_samr_choice which_ops)
 {
        NTSTATUS status;
        struct samr_CreateUser2 r;
@@ -2663,12 +2677,19 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
                
                status = dcerpc_samr_CreateUser2(p, user_ctx, &r);
                
-               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-                       talloc_free(user_ctx);
-                       printf("Server refused create of '%s'\n", r.in.account_name->string);
-                       continue;
+               if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(tctx, SID_BUILTIN))) {
+                       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                               printf("Server correctly refused create of '%s'\n", r.in.account_name->string);
+                               continue;
+                       } else {
+                               printf("Server should have refused create of '%s', got %s instead\n", r.in.account_name->string, 
+                                      nt_errstr(status));
+                               ret = false;
+                               continue;
+                       }
+               }
 
-               } else if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
                        if (!test_DeleteUser_byname(p, user_ctx, domain_handle, r.in.account_name->string)) {
                                talloc_free(user_ctx);
                                ret = false;
@@ -3893,6 +3914,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        }
        
        if (!q1.out.sam) {
+               printf("EnumDomainGroups failed to return q1.out.sam\n");
                return false;
        }
 
@@ -4138,7 +4160,9 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
 
 
 static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-                                  struct policy_handle *domain_handle, struct policy_handle *group_handle)
+                                  struct policy_handle *domain_handle, 
+                                  struct policy_handle *group_handle,
+                                  struct dom_sid *domain_sid)
 {
        NTSTATUS status;
        struct samr_CreateDomainGroup r;
@@ -4158,15 +4182,19 @@ static bool test_CreateDomainGroup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        status = dcerpc_samr_CreateDomainGroup(p, mem_ctx, &r);
 
-       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-               printf("Server refused create of '%s'\n", r.in.name->string);
-               ZERO_STRUCTP(group_handle);
-               return true;
+       if (dom_sid_equal(domain_sid, dom_sid_parse_talloc(mem_ctx, SID_BUILTIN))) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+                       printf("Server correctly refused create of '%s'\n", r.in.name->string);
+                       return true;
+               } else {
+                       printf("Server should have refused create of '%s', got %s instead\n", r.in.name->string, 
+                              nt_errstr(status));
+                       return false;
+               }
        }
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_GROUP_EXISTS)) {
                if (!test_DeleteGroup_byname(p, mem_ctx, domain_handle, r.in.name->string)) {
-                       
                        printf("CreateDomainGroup failed: Could not delete domain group %s - %s\n", r.in.name->string, 
                               nt_errstr(status));
                        return false;
@@ -4244,7 +4272,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
        ZERO_STRUCT(group_handle);
        ZERO_STRUCT(domain_handle);
 
-       printf("Testing OpenDomain\n");
+       printf("Testing OpenDomain of %s\n", dom_sid_string(tctx, sid));
 
        r.in.connect_handle = handle;
        r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -4264,17 +4292,23 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
        switch (which_ops) {
        case TORTURE_SAMR_USER_ATTRIBUTES:
        case TORTURE_SAMR_PASSWORDS:
-               ret &= test_CreateUser2(p, tctx, &domain_handle, which_ops);
-               ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
+               ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
+               ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
                /* This test needs 'complex' users to validate */
                ret &= test_QueryDisplayInfo(p, tctx, &domain_handle);
+               if (!ret) {
+                       printf("Testing PASSWORDS or ATTRIBUTES on domain %s failed!\n", dom_sid_string(tctx, sid));
+               }
                break;
        case TORTURE_SAMR_OTHER:
-               ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, which_ops);
+               ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
+               if (!ret) {
+                       printf("Failed to CreateUser in SAMR-OTHER on domain %s!\n", dom_sid_string(tctx, sid));
+               }
                ret &= test_QuerySecurity(p, tctx, &domain_handle);
                ret &= test_RemoveMemberFromForeignDomain(p, tctx, &domain_handle);
                ret &= test_CreateAlias(p, tctx, &domain_handle, &alias_handle, sid);
-               ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle);
+               ret &= test_CreateDomainGroup(p, tctx, &domain_handle, &group_handle, sid);
                ret &= test_QueryDomainInfo(p, tctx, &domain_handle);
                ret &= test_QueryDomainInfo2(p, tctx, &domain_handle);
                ret &= test_EnumDomainUsers(p, tctx, &domain_handle);
@@ -4295,6 +4329,9 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
                ret &= test_TestPrivateFunctionsDomain(p, tctx, &domain_handle);
                ret &= test_RidToSid(p, tctx, sid, &domain_handle);
                ret &= test_GetBootKeyInformation(p, tctx, &domain_handle);
+               if (!ret) {
+                       printf("Testing SAMR-OTHER on domain %s failed!\n", dom_sid_string(tctx, sid));
+               }
                break;
        }
 
index 2567d617da946e29fe50bf0e619605b1b766bd13..8c9b3f1225d7ab8697728a490ccd8d4895147595 100644 (file)
@@ -16,6 +16,8 @@ OBJ_FILES = \
                wb_dom_info_trusted.o \
                wb_sid2domain.o \
                wb_name2domain.o \
+               wb_sids2xids.o \
+               wb_xids2sids.o \
                wb_gid2sid.o \
                wb_sid2uid.o \
                wb_sid2gid.o \
index 3372ad51eea7478fd703dbaa9ec041061ea569b5..de8a43ec02c24df626017d93beb0ca30dff8f785 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Unix SMB/CIFS implementation.
 
-   Map SIDs to uids/gids and back
+   Map SIDs to unixids and back
 
    Copyright (C) Kai Blin 2008
 
@@ -177,39 +177,46 @@ struct idmap_context *idmap_init(TALLOC_CTX *mem_ctx,
                return NULL;
        }
 
+       idmap_ctx->unix_groups_sid = dom_sid_parse_talloc(mem_ctx, "S-1-22-2");
+       if (idmap_ctx->unix_groups_sid == NULL) {
+               return NULL;
+       }
+
+       idmap_ctx->unix_users_sid = dom_sid_parse_talloc(mem_ctx, "S-1-22-1");
+       if (idmap_ctx->unix_users_sid == NULL) {
+               return NULL;
+       }
+
        return idmap_ctx;
 }
 
 /**
- * Convert a uid to the corresponding SID
+ * Convert an unixid to the corresponding SID
  *
  * \param idmap_ctx idmap context to use
  * \param mem_ctx talloc context the memory for the struct dom_sid is allocated
  * from.
- * \param uid Unix uid to map to a SID
- * \param sid Pointer that will take the struct dom_sid pointer if the mapping
+ * \param unixid pointer to a unixid struct to convert
+ * \param sid pointer that will take the struct dom_sid pointer if the mapping
  * succeeds.
  * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping not
  * possible or some other NTSTATUS that is more descriptive on failure.
  */
 
-NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
-               const uid_t uid, struct dom_sid **sid)
+NTSTATUS idmap_xid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
+               const struct unixid *unixid, struct dom_sid **sid)
 {
        int ret;
        NTSTATUS status = NT_STATUS_NONE_MAPPED;
        struct ldb_context *ldb = idmap_ctx->ldb_ctx;
-       struct ldb_message *msg;
        struct ldb_result *res = NULL;
-       int trans = -1;
-       uid_t low, high;
-       char *sid_string, *uid_string;
-       struct dom_sid *unix_users_sid, *new_sid;
+       uint32_t low, high;
+       struct dom_sid *unix_sid, *new_sid;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
        ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                                NULL, "(&(objectClass=sidMap)(uidNumber=%u))",
-                                uid);
+                                NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
+                                unixid->id);
        if (ret != LDB_SUCCESS) {
                DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
                status = NT_STATUS_NONE_MAPPED;
@@ -228,19 +235,13 @@ NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
        }
 
-       DEBUG(6, ("uid not found in idmap db, trying to allocate SID.\n"));
-
-       trans = ldb_transaction_start(ldb);
-       if (trans != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
+       DEBUG(6, ("xid not found in idmap db, trying to allocate SID.\n"));
 
        /* Now redo the search to make sure noone added a mapping for that SID
         * while we weren't looking.*/
        ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                                NULL, "(&(objectClass=sidMap)(uidNumber=%u))",
-                                uid);
+                                NULL, "(&(objectClass=sidMap)(xidNumber=%u))",
+                                unixid->id);
        if (ret != LDB_SUCCESS) {
                DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
                status = NT_STATUS_NONE_MAPPED;
@@ -260,285 +261,58 @@ NTSTATUS idmap_uid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       if (uid >= low && uid <= high) {
-               /* An existing user would have been mapped before */
-               status = NT_STATUS_NO_SUCH_USER;
+       if (unixid->id >= low && unixid->id <= high) {
+               /* An existing xid would have been mapped before */
+               status = NT_STATUS_NONE_MAPPED;
                goto failed;
        }
 
        /* For local users, we just create a rid = uid +1, so root doesn't end
         * up with a 0 rid */
-       unix_users_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-1");
-       if (unix_users_sid == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       new_sid = dom_sid_add_rid(mem_ctx, unix_users_sid, uid + 1);
-       if (new_sid == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       sid_string = dom_sid_string(tmp_ctx, new_sid);
-       if (sid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       uid_string = talloc_asprintf(tmp_ctx, "%u", uid);
-       if (uid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       msg = ldb_msg_new(tmp_ctx);
-       if (msg == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
-       if (msg->dn == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "uidNumber", uid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, msg, "objectSid",
-                                   new_sid);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "objectClass", "sidMap");
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "cn", sid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_add(ldb, msg);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       trans = ldb_transaction_commit(ldb);
-       if (trans != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       *sid = new_sid;
-       talloc_free(tmp_ctx);
-       return NT_STATUS_OK;
-
-failed:
-       if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
-       talloc_free(tmp_ctx);
-       return status;
-}
-
-/**
- * Map a Unix gid to the corresponding SID
- *
- * \param idmap_ctx idmap context to use
- * \param mem_ctx talloc context the memory for the struct dom_sid is allocated
- * from.
- * \param gid Unix gid to map to a SID
- * \param sid Pointer that will take the struct dom_sid pointer if mapping
- * succeeds.
- * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping not
- * possible or some other NTSTATUS that is more descriptive on failure.
- */
-NTSTATUS idmap_gid_to_sid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
-               const gid_t gid, struct dom_sid **sid)
-{
-       int ret;
-       NTSTATUS status = NT_STATUS_NONE_MAPPED;
-       struct ldb_context *ldb = idmap_ctx->ldb_ctx;
-       struct ldb_message *msg;
-       struct ldb_result *res = NULL;
-       int trans = -1;
-       gid_t low, high;
-       char *sid_string, *gid_string;
-       struct dom_sid *unix_groups_sid, *new_sid;
-       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-
-       ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                       NULL, "(&(objectClass=sidMap)(gidNumber=%u))", gid);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       if (res->count == 1) {
-               *sid = idmap_msg_get_dom_sid(mem_ctx, res->msgs[0],
-                               "objectSid");
-               if (*sid == NULL) {
-                       DEBUG(1, ("Failed to get sid from db: %u\n", ret));
-                       status = NT_STATUS_NONE_MAPPED;
-                       goto failed;
-               }
-               /* No change, so cancel the transaction */
-               ldb_transaction_cancel(ldb);
-               talloc_free(tmp_ctx);
-               return NT_STATUS_OK;
-       }
-
-       DEBUG(6, ("gid not found in idmap db, trying to allocate SID.\n"));
-
-       trans = ldb_transaction_start(ldb);
-       if (trans != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       /* Now redo the search to make sure noone added a mapping for that SID
-        * while we weren't looking.*/
-       ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                                NULL, "(&(objectClass=sidMap)(gidNumber=%u))",
-                                gid);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       if (res->count > 0) {
-               DEBUG(1, ("sidMap modified while trying to add a mapping.\n"));
-               status = NT_STATUS_RETRY;
-               goto failed;
-       }
-
-       ret = idmap_get_bounds(idmap_ctx, &low, &high);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Failed to get id bounds from db: %u\n", ret));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       if (gid >= low && gid <= high) {
-               /* An existing group would have been mapped before */
-               status = NT_STATUS_NO_SUCH_USER;
-               goto failed;
+       if (unixid->type == ID_TYPE_UID) {
+               unix_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-1");
+       } else {
+               unix_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-2");
        }
-
-       /* For local groups, we just create a rid = gid +1, so root doesn't end
-        * up with a 0 rid */
-       unix_groups_sid = dom_sid_parse_talloc(tmp_ctx, "S-1-22-2");
-       if (unix_groups_sid == NULL) {
+       if (unix_sid == NULL) {
                status = NT_STATUS_NO_MEMORY;
                goto failed;
        }
 
-       new_sid = dom_sid_add_rid(mem_ctx, unix_groups_sid, gid + 1);
+       new_sid = dom_sid_add_rid(mem_ctx, unix_sid, unixid->id + 1);
        if (new_sid == NULL) {
                status = NT_STATUS_NO_MEMORY;
                goto failed;
        }
 
-       sid_string = dom_sid_string(tmp_ctx, new_sid);
-       if (sid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       gid_string = talloc_asprintf(tmp_ctx, "%u", gid);
-       if (gid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       msg = ldb_msg_new(tmp_ctx);
-       if (msg == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
-       if (msg->dn == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "gidNumber", gid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, msg, "objectSid",
-                       new_sid);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "objectClass", "sidMap");
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(msg, "cn", sid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_add(ldb, msg);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       trans = ldb_transaction_commit(ldb);
-       if (trans != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
        *sid = new_sid;
        talloc_free(tmp_ctx);
        return NT_STATUS_OK;
 
 failed:
-       if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
        talloc_free(tmp_ctx);
        return status;
 }
 
+
 /**
- * Map a SID to a Unix uid.
+ * Map a SID to an unixid struct.
  *
  * If no mapping exists, a new mapping will be created.
  *
  * \todo Check if SIDs can be resolved if lp_idmap_trusted_only() == true
+ * \todo Fix backwards compatibility for Samba3
  *
  * \param idmap_ctx idmap context to use
  * \param mem_ctx talloc context to use
- * \param sid SID to map to a Unix uid
- * \param uid pointer to receive the mapped uid
+ * \param sid SID to map to an unixid struct
+ * \param unixid pointer to a unixid struct pointer
  * \return NT_STATUS_OK on success, NT_STATUS_INVALID_SID if the sid is not from
  * a trusted domain and idmap trusted only = true, NT_STATUS_NONE_MAPPED if the
  * mapping failed.
  */
-NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
-               const struct dom_sid *sid, uid_t *uid)
+NTSTATUS idmap_sid_to_xid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
+               const struct dom_sid *sid, struct unixid **unixid)
 {
        int ret;
        NTSTATUS status = NT_STATUS_NONE_MAPPED;
@@ -547,8 +321,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
        struct ldb_message *hwm_msg, *map_msg;
        struct ldb_result *res = NULL;
        int trans;
-       uid_t low, high, hwm, new_uid;
-       char *sid_string, *uid_string, *hwm_string;
+       uint32_t low, high, hwm, new_xid;
+       char *sid_string, *unixid_string, *hwm_string;
        bool hwm_entry_exists;
        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
@@ -562,20 +336,65 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
        }
 
        if (res->count == 1) {
-               new_uid = ldb_msg_find_attr_as_uint(res->msgs[0], "uidNumber",
+               new_xid = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber",
                                                    -1);
-               if (new_uid == (uid_t) -1) {
-                       DEBUG(1, ("Invalid uid mapping.\n"));
+               if (new_xid == (uint32_t) -1) {
+                       DEBUG(1, ("Invalid xid mapping.\n"));
                        status = NT_STATUS_NONE_MAPPED;
                        goto failed;
                }
-               *uid = new_uid;
+
+               *unixid = talloc(mem_ctx, struct unixid);
+               if (*unixid == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto failed;
+               }
+
+               (*unixid)->id = new_xid;
+               (*unixid)->type = ID_TYPE_BOTH;
+
                talloc_free(tmp_ctx);
                return NT_STATUS_OK;
        }
 
        DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
 
+       if (dom_sid_in_domain(idmap_ctx->unix_users_sid, sid)) {
+               uint32_t rid;
+               DEBUG(6, ("This is a local unix uid, just calculate that.\n"));
+               status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+               if (!NT_STATUS_IS_OK(status)) goto failed;
+
+               *unixid = talloc(mem_ctx, struct unixid);
+               if (*unixid == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto failed;
+               }
+               (*unixid)->id = rid - 1;
+               (*unixid)->type = ID_TYPE_UID;
+
+               talloc_free(tmp_ctx);
+               return NT_STATUS_OK;
+       }
+
+       if (dom_sid_in_domain(idmap_ctx->unix_groups_sid, sid)) {
+               uint32_t rid;
+               DEBUG(6, ("This is a local unix gid, just calculate that.\n"));
+               status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+               if (!NT_STATUS_IS_OK(status)) goto failed;
+
+               *unixid = talloc(mem_ctx, struct unixid);
+               if (*unixid == NULL) {
+                       status = NT_STATUS_NO_MEMORY;
+                       goto failed;
+               }
+               (*unixid)->id = rid - 1;
+               (*unixid)->type = ID_TYPE_GID;
+
+               talloc_free(tmp_ctx);
+               return NT_STATUS_OK;
+        }
+
        trans = ldb_transaction_start(ldb);
        if (trans != LDB_SUCCESS) {
                status = NT_STATUS_NONE_MAPPED;
@@ -629,8 +448,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "uidNumber", -1);
-       if (hwm == (uid_t)-1) {
+       hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "xidNumber", -1);
+       if (hwm == (uint32_t)-1) {
                hwm = low;
                hwm_entry_exists = false;
        } else {
@@ -638,7 +457,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
        }
 
        if (hwm > high) {
-               DEBUG(1, ("Out of uids to allocate.\n"));
+               DEBUG(1, ("Out of xids to allocate.\n"));
                status = NT_STATUS_NONE_MAPPED;
                goto failed;
        }
@@ -652,7 +471,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
 
        hwm_msg->dn = dn;
 
-       new_uid = hwm;
+       new_xid = hwm;
        hwm++;
 
        hwm_string = talloc_asprintf(tmp_ctx, "%u", hwm);
@@ -667,8 +486,8 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       uid_string = talloc_asprintf(tmp_ctx, "%u", new_uid);
-       if (uid_string == NULL) {
+       unixid_string = talloc_asprintf(tmp_ctx, "%u", new_xid);
+       if (unixid_string == NULL) {
                status = NT_STATUS_NO_MEMORY;
                goto failed;
        }
@@ -696,7 +515,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                els[0].num_values = 1;
                els[0].values = &vals[0];
                els[0].flags = LDB_FLAG_MOD_DELETE;
-               els[0].name = talloc_strdup(tmp_ctx, "uidNumber");
+               els[0].name = talloc_strdup(tmp_ctx, "xidNumber");
                if (els[0].name == NULL) {
                        status = NT_STATUS_NO_MEMORY;
                        goto failed;
@@ -707,19 +526,19 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                els[1].flags = LDB_FLAG_MOD_ADD;
                els[1].name = els[0].name;
 
-               vals[0].data = (uint8_t *)uid_string;
-               vals[0].length = strlen(uid_string);
+               vals[0].data = (uint8_t *)unixid_string;
+               vals[0].length = strlen(unixid_string);
                vals[1].data = (uint8_t *)hwm_string;
                vals[1].length = strlen(hwm_string);
        } else {
-               ret = ldb_msg_add_empty(hwm_msg, "uidNumber", LDB_FLAG_MOD_ADD,
+               ret = ldb_msg_add_empty(hwm_msg, "xidNumber", LDB_FLAG_MOD_ADD,
                                        NULL);
                if (ret != LDB_SUCCESS) {
                        status = NT_STATUS_NONE_MAPPED;
                        goto failed;
                }
 
-               ret = ldb_msg_add_string(hwm_msg, "uidNumber", hwm_string);
+               ret = ldb_msg_add_string(hwm_msg, "xidNumber", hwm_string);
                if (ret != LDB_SUCCESS)
                {
                        status = NT_STATUS_NONE_MAPPED;
@@ -729,7 +548,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
 
        ret = ldb_modify(ldb, hwm_msg);
        if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Updating the uid high water mark failed: %s\n",
+               DEBUG(1, ("Updating the xid high water mark failed: %s\n",
                          ldb_errstring(ldb)));
                status = NT_STATUS_NONE_MAPPED;
                goto failed;
@@ -747,7 +566,7 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       ret = ldb_msg_add_string(map_msg, "uidNumber", uid_string);
+       ret = ldb_msg_add_string(map_msg, "xidNumber", unixid_string);
        if (ret != LDB_SUCCESS) {
                status = NT_STATUS_NONE_MAPPED;
                goto failed;
@@ -786,7 +605,14 @@ NTSTATUS idmap_sid_to_uid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
                goto failed;
        }
 
-       *uid = new_uid;
+       *unixid = talloc(mem_ctx, struct unixid);
+       if (*unixid == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
+
+       (*unixid)->id = new_xid;
+       (*unixid)->type = ID_TYPE_BOTH;
        talloc_free(tmp_ctx);
        return NT_STATUS_OK;
 
@@ -797,276 +623,92 @@ failed:
 }
 
 /**
- * Map a SID to a Unix gid.
- *
- * If no mapping exist, a new mapping will be created.
- *
- * \todo Check if SID resolve when lp_idmap_trusted_only() == true
+ * Convert an array of unixids to the corresponding array of SIDs
  *
  * \param idmap_ctx idmap context to use
- * \param mem_ctx talloc context to use
- * \param sid SID to map to a Unix gid
- * \param gid pointer to receive the mapped gid
- * \return NT_STATUS_OK on success, NT_STATUS_INVALID_SID if the sid is not from
- * a trusted domain and idmap trusted only = true, NT_STATUS_NONE_MAPPED if the
- * mapping failed.
+ * \param mem_ctx talloc context the memory for the dom_sids is allocated
+ * from.
+ * \param count length of id_mapping array.
+ * \param id array of id_mappings.
+ * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping is not
+ * possible at all, NT_STATUS_SOME_UNMAPPED if some mappings worked and some
+ * did not.
  */
-NTSTATUS idmap_sid_to_gid(struct idmap_context *idmap_ctx, TALLOC_CTX *mem_ctx,
-               const struct dom_sid *sid, gid_t *gid)
-{
-       int ret;
-       NTSTATUS status = NT_STATUS_NONE_MAPPED;
-       struct ldb_context *ldb = idmap_ctx->ldb_ctx;
-       struct ldb_dn *dn;
-       struct ldb_message *hwm_msg, *map_msg;
-       struct ldb_result *res = NULL;
-       int trans = -1;
-       gid_t low, high, hwm, new_gid;
-       char *sid_string, *gid_string, *hwm_string;
-       bool hwm_entry_exists;
-       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
-       ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                                NULL, "(&(objectClass=sidMap)(objectSid=%s))",
-                                ldap_encode_ndr_dom_sid(tmp_ctx, sid));
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       if (res->count == 1) {
-               new_gid = ldb_msg_find_attr_as_uint(res->msgs[0], "gidNumber",
-                               -1);
-               if (new_gid == (gid_t) -1) {
-                       DEBUG(1, ("Invalid gid mapping.\n"));
-                       status = NT_STATUS_NONE_MAPPED;
-                       goto failed;
+NTSTATUS idmap_xids_to_sids(struct idmap_context *idmap_ctx,
+                           TALLOC_CTX *mem_ctx, int count,
+                           struct id_mapping *id)
+{
+       int i;
+       int error_count = 0;
+
+       for (i = 0; i < count; ++i) {
+               id[i].status = idmap_xid_to_sid(idmap_ctx, mem_ctx,
+                                               id[i].unixid, &id[i].sid);
+               if (NT_STATUS_EQUAL(id[i].status, NT_STATUS_RETRY)) {
+                       id[i].status = idmap_xid_to_sid(idmap_ctx, mem_ctx,
+                                                       id[i].unixid,
+                                                       &id[i].sid);
+               }
+               if (!NT_STATUS_IS_OK(id[i].status)) {
+                       DEBUG(1, ("idmapping failed for id[%d]\n", i));
+                       error_count++;
                }
-               *gid = new_gid;
-               talloc_free(tmp_ctx);
-               return NT_STATUS_OK;
-       }
-
-       DEBUG(6, ("No existing mapping found, attempting to create one.\n"));
-
-       trans = ldb_transaction_start(ldb);
-       if (trans != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       /* Redo the search to make sure noone changed the mapping while we
-        * weren't looking */
-       ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
-                                NULL, "(&(objectClass=sidMap)(objectSid=%s))",
-                                ldap_encode_ndr_dom_sid(tmp_ctx, sid));
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       if (res->count > 0) {
-               DEBUG(1, ("Database changed while trying to add a sidmap.\n"));
-               status = NT_STATUS_RETRY;
-               goto failed;
-       }
-
-       /*FIXME: if lp_idmap_trusted_only() == true, check if SID can be
-        * resolved here. */
-
-       ret = idmap_get_bounds(idmap_ctx, &low, &high);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       dn = ldb_dn_new(tmp_ctx, ldb, "CN=CONFIG");
-       if (dn == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       ret = ldb_search(ldb, dn, LDB_SCOPE_BASE, NULL, NULL, &res);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Search failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       talloc_steal(tmp_ctx, res);
-
-       if (res->count != 1) {
-               DEBUG(1, ("No CN=CONFIG record, idmap database is broken.\n"));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
        }
 
-       hwm = ldb_msg_find_attr_as_uint(res->msgs[0], "gidNumber", -1);
-       if (hwm == (gid_t)-1) {
-               hwm = low;
-               hwm_entry_exists = false;
+       if (error_count == count) {
+               /* Mapping did not work at all. */
+               return NT_STATUS_NONE_MAPPED;
+       } else if (error_count > 0) {
+               /* Some mappings worked, some did not. */
+               return STATUS_SOME_UNMAPPED;
        } else {
-               hwm_entry_exists = true;
-       }
-
-       if (hwm > high) {
-               DEBUG(1, ("Out of gids to allocate.\n"));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       hwm_msg = ldb_msg_new(tmp_ctx);
-       if (hwm_msg == NULL) {
-               DEBUG(1, ("Out of memory when creating ldb_message\n"));
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       hwm_msg->dn = dn;
-
-       new_gid = hwm;
-       hwm++;
-
-       hwm_string = talloc_asprintf(tmp_ctx, "%u", hwm);
-       if (hwm_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       sid_string = dom_sid_string(tmp_ctx, sid);
-       if (sid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       gid_string = talloc_asprintf(tmp_ctx, "%u", new_gid);
-       if (gid_string == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
+               return NT_STATUS_OK;
        }
+}
 
-       if (hwm_entry_exists) {
-               struct ldb_message_element *els;
-               struct ldb_val *vals;
-
-               /* We're modifying the entry, not just adding a new one. */
-               els = talloc_array(tmp_ctx, struct ldb_message_element, 2);
-               if (els == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto failed;
-               }
-
-               vals = talloc_array(tmp_ctx, struct ldb_val, 2);
-               if (els == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto failed;
-               }
-
-               hwm_msg->num_elements = 2;
-               hwm_msg->elements = els;
-
-               els[0].num_values = 1;
-               els[0].values = &vals[0];
-               els[0].flags = LDB_FLAG_MOD_DELETE;
-               els[0].name = talloc_strdup(tmp_ctx, "gidNumber");
-               if (els[0].name == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto failed;
-               }
-
-               els[1].num_values = 1;
-               els[1].values = &vals[1];
-               els[1].flags = LDB_FLAG_MOD_ADD;
-               els[1].name = els[0].name;
+/**
+ * Convert an array of SIDs to the corresponding array of unixids
+ *
+ * \param idmap_ctx idmap context to use
+ * \param mem_ctx talloc context the memory for the unixids is allocated
+ * from.
+ * \param count length of id_mapping array.
+ * \param id array of id_mappings.
+ * \return NT_STATUS_OK on success, NT_STATUS_NONE_MAPPED if mapping is not
+ * possible at all, NT_STATUS_SOME_UNMAPPED if some mappings worked and some
+ * did not.
+ */
 
-               vals[0].data = (uint8_t *)gid_string;
-               vals[0].length = strlen(gid_string);
-               vals[1].data = (uint8_t *)hwm_string;
-               vals[1].length = strlen(hwm_string);
-       } else {
-               ret = ldb_msg_add_empty(hwm_msg, "gidNumber", LDB_FLAG_MOD_ADD,
-                                       NULL);
-               if (ret != LDB_SUCCESS) {
-                       status = NT_STATUS_NONE_MAPPED;
-                       goto failed;
+NTSTATUS idmap_sids_to_xids(struct idmap_context *idmap_ctx,
+                           TALLOC_CTX *mem_ctx, int count,
+                           struct id_mapping *id)
+{
+       int i;
+       int error_count = 0;
+
+       for (i = 0; i < count; ++i) {
+               id[i].status = idmap_sid_to_xid(idmap_ctx, mem_ctx,
+                                               id[i].sid, &id[i].unixid);
+               if (NT_STATUS_EQUAL(id[i].status, NT_STATUS_RETRY)) {
+                       id[i].status = idmap_sid_to_xid(idmap_ctx, mem_ctx,
+                                                       id[i].sid,
+                                                       &id[i].unixid);
                }
-
-               ret = ldb_msg_add_string(hwm_msg, "gidNumber", hwm_string);
-               if (ret != LDB_SUCCESS)
-               {
-                       status = NT_STATUS_NONE_MAPPED;
-                       goto failed;
+               if (!NT_STATUS_IS_OK(id[i].status)) {
+                       DEBUG(1, ("idmapping failed for id[%d]\n", i));
+                       error_count++;
                }
        }
 
-       ret = ldb_modify(ldb, hwm_msg);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Updating the gid high water mark failed: %s\n",
-                         ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       map_msg = ldb_msg_new(tmp_ctx);
-       if (map_msg == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       map_msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s", sid_string);
-       if (map_msg->dn == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(map_msg, "gidNumber", gid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = idmap_msg_add_dom_sid(idmap_ctx, tmp_ctx, map_msg, "objectSid",
-                       sid);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(map_msg, "objectClass", "sidMap");
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_msg_add_string(map_msg, "cn", sid_string);
-       if (ret != LDB_SUCCESS) {
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       ret = ldb_add(ldb, map_msg);
-       if (ret != LDB_SUCCESS) {
-               DEBUG(1, ("Adding a sidmap failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
-       }
-
-       trans = ldb_transaction_commit(ldb);
-       if (trans != LDB_SUCCESS) {
-               DEBUG(1, ("Transaction failed: %s\n", ldb_errstring(ldb)));
-               status = NT_STATUS_NONE_MAPPED;
-               goto failed;
+       if (error_count == count) {
+               /* Mapping did not work at all. */
+               return NT_STATUS_NONE_MAPPED;
+       } else if (error_count > 0) {
+               /* Some mappings worked, some did not. */
+               return STATUS_SOME_UNMAPPED;
+       } else {
+               return NT_STATUS_OK;
        }
-
-       *gid = new_gid;
-       talloc_free(tmp_ctx);
-       return NT_STATUS_OK;
-
-failed:
-       if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
-       talloc_free(tmp_ctx);
-       return status;
 }
 
index 8781819be02883e35f3668f24b815669c2505283..045d50c568b593f0a9bd1cfcf3d511e1e5c46bde 100644 (file)
 struct idmap_context {
        struct loadparm_context *lp_ctx;
        struct ldb_context *ldb_ctx;
+       struct dom_sid *unix_groups_sid;
+       struct dom_sid *unix_users_sid;
+};
+
+enum id_type {
+        ID_TYPE_NOT_SPECIFIED = 0,
+        ID_TYPE_UID,
+        ID_TYPE_GID,
+       ID_TYPE_BOTH
+};
+
+struct unixid {
+        uint32_t id;
+        enum id_type type;
+};
+
+struct id_mapping {
+       struct unixid *unixid;
+       struct dom_sid *sid;
+       NTSTATUS status;
 };
 
 #include "winbind/idmap_proto.h"
index f2577029aaba2c3dec46e21ea567abecfbb49d6b..834d869845e2d5811d605f6fc4c0630a0dadeecf 100644 (file)
@@ -3,7 +3,7 @@
 
    Command backend for wbinfo -G
 
-   Copyright (C) Kai Blin 2007
+   Copyright (C) 2007-2008 Kai Blin
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,35 +33,60 @@ struct gid2sid_state {
        struct dom_sid *sid;
 };
 
+static void gid2sid_recv_sid(struct composite_context *ctx);
+
 struct composite_context *wb_gid2sid_send(TALLOC_CTX *mem_ctx,
                struct wbsrv_service *service, gid_t gid)
 {
-       struct composite_context *result;
+       struct composite_context *result, *ctx;
        struct gid2sid_state *state;
+       struct unixid *unixid;
+       struct id_mapping *ids;
 
        DEBUG(5, ("wb_gid2sid_send called\n"));
 
        result = composite_create(mem_ctx, service->task->event_ctx);
        if (!result) return NULL;
 
-       state = talloc(mem_ctx, struct gid2sid_state);
+       state = talloc(result, struct gid2sid_state);
        if (composite_nomem(state, result)) return result;
 
        state->ctx = result;
        result->private_data = state;
        state->service = service;
 
-       state->ctx->status = idmap_gid_to_sid(service->idmap_ctx, mem_ctx, gid,
-                                             &state->sid);
-       if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
-               state->ctx->status = idmap_gid_to_sid(service->idmap_ctx,
-                                                     mem_ctx, gid,
-                                                     &state->sid);
+       unixid = talloc(result, struct unixid);
+       if (composite_nomem(unixid, result)) return result;
+       unixid->id = gid;
+       unixid->type = ID_TYPE_GID;
+
+       ids = talloc(result, struct id_mapping);
+       if (composite_nomem(ids, result)) return result;
+       ids->unixid = unixid;
+       ids->sid = NULL;
+
+       ctx = wb_xids2sids_send(result, service, 1, ids);
+       if (composite_nomem(ctx, result)) return result;
+
+       composite_continue(result, ctx, gid2sid_recv_sid, state);
+       return result;
+}
+
+static void gid2sid_recv_sid(struct composite_context *ctx)
+{
+       struct gid2sid_state *state = talloc_get_type(ctx->async.private_data,
+                                                     struct gid2sid_state);
+       struct id_mapping *ids = NULL;
+       state->ctx->status = wb_xids2sids_recv(ctx, &ids);
+       if (!composite_is_ok(state->ctx)) return;
+
+       if (!NT_STATUS_IS_OK(ids->status)) {
+               composite_error(state->ctx, ids->status);
+               return;
        }
-       if (!composite_is_ok(state->ctx)) return result;
 
+       state->sid = ids->sid;
        composite_done(state->ctx);
-       return result;
 }
 
 NTSTATUS wb_gid2sid_recv(struct composite_context *ctx, TALLOC_CTX *mem_ctx,
index 12129226be5ac94bc1ffaf58a0b8b8c2027b20fa..d68956ce85175a4a8592e2b2319c716f397aab71 100644 (file)
@@ -3,7 +3,7 @@
 
    Map a SID to a gid
 
-   Copyright (C) Kai Blin 2007
+   Copyright (C) 2007-2008  Kai Blin
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,11 +33,14 @@ struct sid2gid_state {
        gid_t gid;
 };
 
+static void sid2gid_recv_gid(struct composite_context *ctx);
+
 struct composite_context *wb_sid2gid_send(TALLOC_CTX *mem_ctx,
                struct wbsrv_service *service, const struct dom_sid *sid)
 {
-       struct composite_context *result;
+       struct composite_context *result, *ctx;
        struct sid2gid_state *state;
+       struct id_mapping *ids;
 
        DEBUG(5, ("wb_sid2gid_send called\n"));
 
@@ -51,18 +54,43 @@ struct composite_context *wb_sid2gid_send(TALLOC_CTX *mem_ctx,
        result->private_data = state;
        state->service = service;
 
-       state->ctx->status = idmap_sid_to_gid(service->idmap_ctx, state, sid,
-                                             &state->gid);
-       if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
-               state->ctx->status = idmap_sid_to_gid(service->idmap_ctx, state,
-                                                     sid, &state->gid);
-       }
-       if (!composite_is_ok(state->ctx)) return result;
+       ids = talloc(result, struct id_mapping);
+       if (composite_nomem(ids, result)) return result;
+
+       ids->sid = dom_sid_dup(result, sid);
+       if (composite_nomem(ids->sid, result)) return result;
+
+       ctx = wb_sids2xids_send(result, service, 1, ids);
+       if (composite_nomem(ctx, result)) return result;
 
-       composite_done(state->ctx);
+       composite_continue(result, ctx, sid2gid_recv_gid, state);
        return result;
 }
 
+static void sid2gid_recv_gid(struct composite_context *ctx)
+{
+       struct sid2gid_state *state = talloc_get_type(ctx->async.private_data,
+                                                     struct sid2gid_state);
+
+       struct id_mapping *ids = NULL;
+
+       state->ctx->status = wb_sids2xids_recv(ctx, &ids);
+       if (!composite_is_ok(state->ctx)) return;
+
+       if (!NT_STATUS_IS_OK(ids->status)) {
+               composite_error(state->ctx, ids->status);
+               return;
+       }
+
+       if (ids->unixid->type == ID_TYPE_BOTH ||
+           ids->unixid->type == ID_TYPE_GID) {
+               state->gid = ids->unixid->id;
+               composite_done(state->ctx);
+       } else {
+               composite_error(state->ctx, NT_STATUS_INVALID_SID);
+       }
+}
+
 NTSTATUS wb_sid2gid_recv(struct composite_context *ctx, gid_t *gid)
 {
        NTSTATUS status = composite_wait(ctx);
index 0de45fdea9b50065e1eb637490ee9a301ca51574..b65e41978cc3f3e809ae54ab02a7fb8e6a9148ab 100644 (file)
@@ -3,7 +3,7 @@
 
    Map a SID to a uid
 
-   Copyright (C) Kai Blin 2007-2008
+   Copyright (C) 2007-2008 Kai Blin
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,11 +33,14 @@ struct sid2uid_state {
        uid_t uid;
 };
 
+static void sid2uid_recv_uid(struct composite_context *ctx);
+
 struct composite_context *wb_sid2uid_send(TALLOC_CTX *mem_ctx,
                struct wbsrv_service *service, const struct dom_sid *sid)
 {
-       struct composite_context *result;
+       struct composite_context *result, *ctx;
        struct sid2uid_state *state;
+       struct id_mapping *ids;
 
        DEBUG(5, ("wb_sid2uid_send called\n"));
 
@@ -45,24 +48,49 @@ struct composite_context *wb_sid2uid_send(TALLOC_CTX *mem_ctx,
        if (!result) return NULL;
 
        state = talloc(result, struct sid2uid_state);
-       if(composite_nomem(state, result)) return result;
+       if (composite_nomem(state, result)) return result;
 
        state->ctx = result;
        result->private_data = state;
        state->service = service;
 
-       state->ctx->status = idmap_sid_to_uid(service->idmap_ctx, state, sid,
-                                             &state->uid);
-       if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
-               state->ctx->status = idmap_sid_to_uid(service->idmap_ctx, state,
-                                                     sid, &state->uid);
-       }
-       if (!composite_is_ok(state->ctx)) return result;
+       ids = talloc(result, struct id_mapping);
+       if (composite_nomem(ids, result)) return result;
+
+       ids->sid = dom_sid_dup(result, sid);
+       if (composite_nomem(ids->sid, result)) return result;
+
+       ctx = wb_sids2xids_send(result, service, 1, ids);
+       if (composite_nomem(ctx, result)) return result;
 
-       composite_done(state->ctx);
+       composite_continue(result, ctx, sid2uid_recv_uid, state);
        return result;
 }
 
+static void sid2uid_recv_uid(struct composite_context *ctx)
+{
+       struct sid2uid_state *state = talloc_get_type(ctx->async.private_data,
+                                                     struct sid2uid_state);
+
+       struct id_mapping *ids = NULL;
+
+       state->ctx->status = wb_sids2xids_recv(ctx, &ids);
+       if (!composite_is_ok(state->ctx)) return;
+
+       if (!NT_STATUS_IS_OK(ids->status)) {
+               composite_error(state->ctx, ids->status);
+               return;
+       }
+
+       if (ids->unixid->type == ID_TYPE_BOTH ||
+           ids->unixid->type == ID_TYPE_UID) {
+               state->uid = ids->unixid->id;
+               composite_done(state->ctx);
+       } else {
+               composite_error(state->ctx, NT_STATUS_INVALID_SID);
+       }
+}
+
 NTSTATUS wb_sid2uid_recv(struct composite_context *ctx, uid_t *uid)
 {
        NTSTATUS status = composite_wait(ctx);
diff --git a/source/winbind/wb_sids2xids.c b/source/winbind/wb_sids2xids.c
new file mode 100644 (file)
index 0000000..302b915
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Map SIDs to unixids.
+
+   Copyright (C) 2008 Kai Blin
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/composite/composite.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_task.h"
+#include "winbind/wb_helper.h"
+#include "libcli/security/proto.h"
+#include "winbind/idmap.h"
+
+struct sids2xids_state {
+       struct composite_context *ctx;
+       struct wbsrv_service *service;
+       struct id_mapping *ids;
+       int count;
+};
+
+struct composite_context *wb_sids2xids_send(TALLOC_CTX *mem_ctx,
+                                           struct wbsrv_service *service,
+                                           int count, struct id_mapping *ids)
+{
+       struct composite_context *result;
+       struct sids2xids_state *state;
+
+       DEBUG(5, ("wb_sids2xids_send called\n"));
+
+       result = composite_create(mem_ctx, service->task->event_ctx);
+       if (!result) return NULL;
+
+       state = talloc(result, struct sids2xids_state);
+       if (composite_nomem(state, result)) return result;
+
+       state->ctx = result;
+       result->private_data = state;
+       state->service = service;
+       state->count = count;
+       state->ids = ids;
+
+       state->ctx->status = idmap_sids_to_xids(service->idmap_ctx, mem_ctx,
+                                               count, state->ids);
+       if (!composite_is_ok(state->ctx)) return result;
+
+       composite_done(state->ctx);
+       return result;
+}
+
+NTSTATUS wb_sids2xids_recv(struct composite_context *ctx,
+                          struct id_mapping **ids)
+{
+       NTSTATUS status = composite_wait(ctx);
+
+       DEBUG(5, ("wb_sids2xids_recv called\n"));
+
+       if (NT_STATUS_IS_OK(status)) {
+               struct sids2xids_state *state =
+                       talloc_get_type(ctx->private_data,
+                               struct sids2xids_state);
+               *ids = state->ids;
+       }
+       talloc_free(ctx);
+       return status;
+}
+
index e81d2e46717e4ad168fa4f4c0ab14325ab7ed409..fd43dd64b99621554d55ba55acc106de48e62677 100644 (file)
@@ -3,7 +3,7 @@
 
    Command backend for wbinfo -U
 
-   Copyright (C) Kai Blin 2007-2008
+   Copyright (C) 2007-2008 Kai Blin
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -33,35 +33,62 @@ struct uid2sid_state {
        struct dom_sid *sid;
 };
 
+static void uid2sid_recv_sid(struct composite_context *ctx);
+
 struct composite_context *wb_uid2sid_send(TALLOC_CTX *mem_ctx,
                struct wbsrv_service *service, uid_t uid)
 {
-       struct composite_context *result;
+       struct composite_context *result, *ctx;
        struct uid2sid_state *state;
+       struct unixid *unixid;
+       struct id_mapping *ids;
 
        DEBUG(5, ("wb_uid2sid_send called\n"));
 
        result = composite_create(mem_ctx, service->task->event_ctx);
        if (!result) return NULL;
 
-       state = talloc(mem_ctx, struct uid2sid_state);
+       state = talloc(result, struct uid2sid_state);
        if (composite_nomem(state, result)) return result;
 
        state->ctx = result;
        result->private_data = state;
        state->service = service;
 
-       state->ctx->status = idmap_uid_to_sid(service->idmap_ctx, mem_ctx, uid,
-                                             &state->sid);
-       if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_RETRY)) {
-               state->ctx->status = idmap_uid_to_sid(service->idmap_ctx,
-                                                     mem_ctx, uid,
-                                                     &state->sid);
+       unixid = talloc(result, struct unixid);
+       if (composite_nomem(unixid, result)) return result;
+       unixid->id = uid;
+       unixid->type = ID_TYPE_UID;
+
+       ids = talloc(result, struct id_mapping);
+       if (composite_nomem(ids, result)) return result;
+       ids->unixid = unixid;
+       ids->sid = NULL;
+
+       ctx = wb_xids2sids_send(result, service, 1, ids);
+       if (composite_nomem(ctx, result)) return result;
+
+       composite_continue(result, ctx, uid2sid_recv_sid, state);
+       return result;
+}
+
+static void uid2sid_recv_sid(struct composite_context *ctx)
+{
+       struct uid2sid_state *state = talloc_get_type(ctx->async.private_data,
+                                                     struct uid2sid_state);
+       struct id_mapping *ids = NULL;
+
+       state->ctx->status = wb_xids2sids_recv(ctx, &ids);
+       if (!composite_is_ok(state->ctx)) return;
+
+       if (!NT_STATUS_IS_OK(ids->status)) {
+               composite_error(state->ctx, ids->status);
+               return;
        }
-       if (!composite_is_ok(state->ctx)) return result;
+
+       state->sid = ids->sid;
 
        composite_done(state->ctx);
-       return result;
 }
 
 NTSTATUS wb_uid2sid_recv(struct composite_context *ctx, TALLOC_CTX *mem_ctx,
diff --git a/source/winbind/wb_xids2sids.c b/source/winbind/wb_xids2sids.c
new file mode 100644 (file)
index 0000000..843d292
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Convet an unixid struct to a SID
+
+   Copyright (C) 2008 Kai Blin
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/composite/composite.h"
+#include "winbind/wb_server.h"
+#include "smbd/service_task.h"
+#include "winbind/wb_helper.h"
+#include "libcli/security/proto.h"
+#include "winbind/idmap.h"
+
+struct xids2sids_state {
+       struct composite_context *ctx;
+       struct wbsrv_service *service;
+       struct id_mapping *ids;
+       int count;
+};
+
+struct composite_context *wb_xids2sids_send(TALLOC_CTX *mem_ctx,
+                                           struct wbsrv_service *service,
+                                           int count, struct id_mapping *ids)
+{
+       struct composite_context *result;
+       struct xids2sids_state *state;
+
+       DEBUG(0, ("wb_xids2sids_send called\n"));
+
+       result = composite_create(mem_ctx, service->task->event_ctx);
+       if (!result) return NULL;
+
+       state = talloc(mem_ctx, struct xids2sids_state);
+       if (composite_nomem(state, result)) return result;
+
+       state->ctx = result;
+       result->private_data = state;
+       state->service = service;
+       state->count = count;
+       state->ids = ids;
+
+       state->ctx->status = idmap_xids_to_sids(service->idmap_ctx, mem_ctx,
+                                               count, state->ids);
+       if (!composite_is_ok(state->ctx)) return result;
+
+       composite_done(state->ctx);
+       return result;
+}
+
+NTSTATUS wb_xids2sids_recv(struct composite_context *ctx,
+                          struct id_mapping **ids)
+{
+       NTSTATUS status = composite_wait(ctx);
+
+       DEBUG(0, ("wb_xids2sids_recv called.\n"));
+
+       if (NT_STATUS_IS_OK(status)) {
+               struct xids2sids_state *state =
+                       talloc_get_type(ctx->private_data,
+                               struct xids2sids_state);
+               *ids = state->ids;
+       }
+       talloc_free(ctx);
+       return status;
+}
+