Net
[ class tree: Net ] [ index: Net ] [ all elements ]

Source for file php5.php

Documentation is available at php5.php

  1. <?php
  2.  
  3. // {{{ license
  4.  
  5. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  6. //
  7. // +----------------------------------------------------------------------+
  8. // | This library is free software; you can redistribute it and/or modify |
  9. // | it under the terms of the GNU Lesser General Public License as       |
  10. // | published by the Free Software Foundation; either version 2.1 of the |
  11. // | License, or (at your option) any later version.                      |
  12. // |                                                                      |
  13. // | This library is distributed in the hope that it will be useful, but  |
  14. // | WITHOUT ANY WARRANTY; without even the implied warranty of           |
  15. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
  16. // | Lesser General Public License for more details.                      |
  17. // |                                                                      |
  18. // | You should have received a copy of the GNU Lesser General Public     |
  19. // | License along with this library; if not, write to the Free Software  |
  20. // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 |
  21. // | USA.                                                                 |
  22. // +----------------------------------------------------------------------+
  23. //
  24.  
  25. // }}}
  26.  
  27.  
  28. /**
  29.  * Encode/decode Internationalized Domain Names.
  30.  *
  31.  * The class allows to convert internationalized domain names
  32.  * (see RFC 3490 for details) as they can be used with various registries worldwide
  33.  * to be translated between their original (localized) form and their encoded form
  34.  * as it will be used in the DNS (Domain Name System).
  35.  *
  36.  * The class provides two public methods, encode() and decode(), which do exactly
  37.  * what you would expect them to do. You are allowed to use complete domain names,
  38.  * simple strings and complete email addresses as well. That means, that you might
  39.  * use any of the following notations:
  40.  *
  41.  * - xn--nrgler-wxa
  42.  * - xn--brse-5qa.xn--knrz-1ra.info
  43.  *
  44.  * Unicode input might be given as either UTF-8 string, UCS-4 string or UCS-4
  45.  * array. Unicode output is available in the same formats.
  46.  * You can select your preferred format via {@link set_paramter()}.
  47.  *
  48.  * ACE input and output is always expected to be ASCII.
  49.  *
  50.  * @author  Markus Nix <mnix@docuverse.de>
  51.  * @author  Matthias Sommerfeld <mso@phlylabs.de>
  52.  * @package Net
  53.  * @version $Id: IDNA.php,v 0.4.1 2005/08/07 18:35 phlylabs_de Exp $
  54.  */
  55.  
  56. {
  57.     // {{{ npdata
  58.     /**
  59.      * These Unicode codepoints are
  60.      * mapped to nothing, See RFC3454 for details
  61.      *
  62.      * @static
  63.      * @var array 
  64.      * @access private
  65.      */
  66.     private static $_np_map_nothing = array(
  67.         0xAD,
  68.         0x34F,
  69.         0x1806,
  70.         0x180B,
  71.         0x180C,
  72.         0x180D,
  73.         0x200B,
  74.         0x200C,
  75.         0x200D,
  76.         0x2060,
  77.         0xFE00,
  78.         0xFE01,
  79.         0xFE02,
  80.         0xFE03,
  81.         0xFE04,
  82.         0xFE05,
  83.         0xFE06,
  84.         0xFE07,
  85.         0xFE08,
  86.         0xFE09,
  87.         0xFE0A,
  88.         0xFE0B,
  89.         0xFE0C,
  90.         0xFE0D,
  91.         0xFE0E,
  92.         0xFE0F,
  93.         0xFEFF
  94.     );
  95.  
  96.     /**
  97.      * Prohibited codepints
  98.      *
  99.      * @static
  100.      * @var array 
  101.      * @access private
  102.      */
  103.     private static $_general_prohibited = array(
  104.         0,
  105.         1,
  106.         2,
  107.         3,
  108.         4,
  109.         5,
  110.         6,
  111.         7,
  112.         8,
  113.         9,
  114.         0xA,
  115.         0xB,
  116.         0xC,
  117.         0xD,
  118.         0xE,
  119.         0xF,
  120.         0x10,
  121.         0x11,
  122.         0x12,
  123.         0x13,
  124.         0x14,
  125.         0x15,
  126.         0x16,
  127.         0x17,
  128.         0x18,
  129.         0x19,
  130.         0x1A,
  131.         0x1B,
  132.         0x1C,
  133.         0x1D,
  134.         0x1E,
  135.         0x1F,
  136.         0x20,
  137.         0x21,
  138.         0x22,
  139.         0x23,
  140.         0x24,
  141.         0x25,
  142.         0x26,
  143.         0x27,
  144.         0x28,
  145.         0x29,
  146.         0x2A,
  147.         0x2B,
  148.         0x2C,
  149.         0x2F,
  150.         0x3B,
  151.         0x3C,
  152.         0x3D,
  153.         0x3E,
  154.         0x3F,
  155.         0x40,
  156.         0x5B,
  157.         0x5C,
  158.         0x5D,
  159.         0x5E,
  160.         0x5F,
  161.         0x60,
  162.         0x7B,
  163.         0x7C,
  164.         0x7D,
  165.         0x7E,
  166.         0x7F,
  167.         0x3002
  168.     );
  169.  
  170.     /**
  171.      * Codepints prohibited by Nameprep
  172.      * @static
  173.      * @var array 
  174.      * @access private
  175.      */
  176.     private static $_np_prohibit = array(
  177.         0xA0,
  178.         0x1680,
  179.         0x2000,
  180.         0x2001,
  181.         0x2002,
  182.         0x2003,
  183.         0x2004,
  184.         0x2005,
  185.         0x2006,
  186.         0x2007,
  187.         0x2008,
  188.         0x2009,
  189.         0x200A,
  190.         0x200B,
  191.         0x202F,
  192.         0x205F,
  193.         0x3000,
  194.         0x6DD,
  195.         0x70F,
  196.         0x180E,
  197.         0x200C,
  198.         0x200D,
  199.         0x2028,
  200.         0x2029,
  201.         0xFEFF,
  202.         0xFFF9,
  203.         0xFFFA,
  204.         0xFFFB,
  205.         0xFFFC,
  206.         0xFFFE,
  207.         0xFFFF,
  208.         0x1FFFE,
  209.         0x1FFFF,
  210.         0x2FFFE,
  211.         0x2FFFF,
  212.         0x3FFFE,
  213.         0x3FFFF,
  214.         0x4FFFE,
  215.         0x4FFFF,
  216.         0x5FFFE,
  217.         0x5FFFF,
  218.         0x6FFFE,
  219.         0x6FFFF,
  220.         0x7FFFE,
  221.         0x7FFFF,
  222.         0x8FFFE,
  223.         0x8FFFF,
  224.         0x9FFFE,
  225.         0x9FFFF,
  226.         0xAFFFE,
  227.         0xAFFFF,
  228.         0xBFFFE,
  229.         0xBFFFF,
  230.         0xCFFFE,
  231.         0xCFFFF,
  232.         0xDFFFE,
  233.         0xDFFFF,
  234.         0xEFFFE,
  235.         0xEFFFF,
  236.         0xFFFFE,
  237.         0xFFFFF,
  238.         0x10FFFE,
  239.         0x10FFFF,
  240.         0xFFF9,
  241.         0xFFFA,
  242.         0xFFFB,
  243.         0xFFFC,
  244.         0xFFFD,
  245.         0x340,
  246.         0x341,
  247.         0x200E,
  248.         0x200F,
  249.         0x202A,
  250.         0x202B,
  251.         0x202C,
  252.         0x202D,
  253.         0x202E,
  254.         0x206A,
  255.         0x206B,
  256.         0x206C,
  257.         0x206D,
  258.         0x206E,
  259.         0x206F,
  260.         0xE0001
  261.     );
  262.  
  263.     /**
  264.      * Codepoint ranges prohibited by nameprep
  265.      *
  266.      * @static
  267.      * @var array 
  268.      * @access private
  269.      */
  270.     private static $_np_prohibit_ranges = array(
  271.         array(0x80,     0x9F    ),
  272.         array(0x2060,   0x206F  ),
  273.         array(0x1D173,  0x1D17A ),
  274.         array(0xE000,   0xF8FF  ),
  275.         array(0xF0000,  0xFFFFD ),
  276.         array(0x1000000x10FFFD),
  277.         array(0xFDD0,   0xFDEF  ),
  278.         array(0xD800,   0xDFFF  ),
  279.         array(0x2FF0,   0x2FFB  ),
  280.         array(0xE0020,  0xE007F )
  281.     );
  282.  
  283.     /**
  284.      * Replacement mappings (casemapping, replacement sequences, ...)
  285.      *
  286.      * @static
  287.      * @var array 
  288.      * @access private
  289.      */
  290.     private static $_np_replacemaps = array(
  291.         0x41    => array(0x61),
  292.         0x42    => array(0x62),
  293.         0x43    => array(0x63),
  294.         0x44    => array(0x64),
  295.         0x45    => array(0x65),
  296.         0x46    => array(0x66),
  297.         0x47    => array(0x67),
  298.         0x48    => array(0x68),
  299.         0x49    => array(0x69),
  300.         0x4A    => array(0x6A),
  301.         0x4B    => array(0x6B),
  302.         0x4C    => array(0x6C),
  303.         0x4D    => array(0x6D),
  304.         0x4E    => array(0x6E),
  305.         0x4F    => array(0x6F),
  306.         0x50    => array(0x70),
  307.         0x51    => array(0x71),
  308.         0x52    => array(0x72),
  309.         0x53    => array(0x73),
  310.         0x54    => array(0x74),
  311.         0x55    => array(0x75),
  312.         0x56    => array(0x76),
  313.         0x57    => array(0x77),
  314.         0x58    => array(0x78),
  315.         0x59    => array(0x79),
  316.         0x5A    => array(0x7A),
  317.         0xB5    => array(0x3BC),
  318.         0xC0    => array(0xE0),
  319.         0xC1    => array(0xE1),
  320.         0xC2    => array(0xE2),
  321.         0xC3    => array(0xE3),
  322.         0xC4    => array(0xE4),
  323.         0xC5    => array(0xE5),
  324.         0xC6    => array(0xE6),
  325.         0xC7    => array(0xE7),
  326.         0xC8    => array(0xE8),
  327.         0xC9    => array(0xE9),
  328.         0xCA    => array(0xEA),
  329.         0xCB    => array(0xEB),
  330.         0xCC    => array(0xEC),
  331.         0xCD    => array(0xED),
  332.         0xCE    => array(0xEE),
  333.         0xCF    => array(0xEF),
  334.         0xD0    => array(0xF0),
  335.         0xD1    => array(0xF1),
  336.         0xD2    => array(0xF2),
  337.         0xD3    => array(0xF3),
  338.         0xD4    => array(0xF4),
  339.         0xD5    => array(0xF5),
  340.         0xD6    => array(0xF6),
  341.         0xD8    => array(0xF8),
  342.         0xD9    => array(0xF9),
  343.         0xDA    => array(0xFA),
  344.         0xDB    => array(0xFB),
  345.         0xDC    => array(0xFC),
  346.         0xDD    => array(0xFD),
  347.         0xDE    => array(0xFE),
  348.         0xDF    => array(0x730x73),
  349.         0x100   => array(0x101),
  350.         0x102   => array(0x103),
  351.         0x104   => array(0x105),
  352.         0x106   => array(0x107),
  353.         0x108   => array(0x109),
  354.         0x10A   => array(0x10B),
  355.         0x10C   => array(0x10D),
  356.         0x10E   => array(0x10F),
  357.         0x110   => array(0x111),
  358.         0x112   => array(0x113),
  359.         0x114   => array(0x115),
  360.         0x116   => array(0x117),
  361.         0x118   => array(0x119),
  362.         0x11A   => array(0x11B),
  363.         0x11C   => array(0x11D),
  364.         0x11E   => array(0x11F),
  365.         0x120   => array(0x121),
  366.         0x122   => array(0x123),
  367.         0x124   => array(0x125),
  368.         0x126   => array(0x127),
  369.         0x128   => array(0x129),
  370.         0x12A   => array(0x12B),
  371.         0x12C   => array(0x12D),
  372.         0x12E   => array(0x12F),
  373.         0x130   => array(0x690x307),
  374.         0x132   => array(0x133),
  375.         0x134   => array(0x135),
  376.         0x136   => array(0x137),
  377.         0x139   => array(0x13A),
  378.         0x13B   => array(0x13C),
  379.         0x13D   => array(0x13E),
  380.         0x13F   => array(0x140),
  381.         0x141   => array(0x142),
  382.         0x143   => array(0x144),
  383.         0x145   => array(0x146),
  384.         0x147   => array(0x148),
  385.         0x149   => array(0x2BC0x6E),
  386.         0x14A   => array(0x14B),
  387.         0x14C   => array(0x14D),
  388.         0x14E   => array(0x14F),
  389.         0x150   => array(0x151),
  390.         0x152   => array(0x153),
  391.         0x154   => array(0x155),
  392.         0x156   => array(0x157),
  393.         0x158   => array(0x159),
  394.         0x15A   => array(0x15B),
  395.         0x15C   => array(0x15D),
  396.         0x15E   => array(0x15F),
  397.         0x160   => array(0x161),
  398.         0x162   => array(0x163),
  399.         0x164   => array(0x165),
  400.         0x166   => array(0x167),
  401.         0x168   => array(0x169),
  402.         0x16A   => array(0x16B),
  403.         0x16C   => array(0x16D),
  404.         0x16E   => array(0x16F),
  405.         0x170   => array(0x171),
  406.         0x172   => array(0x173),
  407.         0x174   => array(0x175),
  408.         0x176   => array(0x177),
  409.         0x178   => array(0xFF),
  410.         0x179   => array(0x17A),
  411.         0x17B   => array(0x17C),
  412.         0x17D   => array(0x17E),
  413.         0x17F   => array(0x73),
  414.         0x181   => array(0x253),
  415.         0x182   => array(0x183),
  416.         0x184   => array(0x185),
  417.         0x186   => array(0x254),
  418.         0x187   => array(0x188),
  419.         0x189   => array(0x256),
  420.         0x18A   => array(0x257),
  421.         0x18B   => array(0x18C),
  422.         0x18E   => array(0x1DD),
  423.         0x18F   => array(0x259),
  424.         0x190   => array(0x25B),
  425.         0x191   => array(0x192),
  426.         0x193   => array(0x260),
  427.         0x194   => array(0x263),
  428.         0x196   => array(0x269),
  429.         0x197   => array(0x268),
  430.         0x198   => array(0x199),
  431.         0x19C   => array(0x26F),
  432.         0x19D   => array(0x272),
  433.         0x19F   => array(0x275),
  434.         0x1A0   => array(0x1A1),
  435.         0x1A2   => array(0x1A3),
  436.         0x1A4   => array(0x1A5),
  437.         0x1A6   => array(0x280),
  438.         0x1A7   => array(0x1A8),
  439.         0x1A9   => array(0x283),
  440.         0x1AC   => array(0x1AD),
  441.         0x1AE   => array(0x288),
  442.         0x1AF   => array(0x1B0),
  443.         0x1B1   => array(0x28A),
  444.         0x1B2   => array(0x28B),
  445.         0x1B3   => array(0x1B4),
  446.         0x1B5   => array(0x1B6),
  447.         0x1B7   => array(0x292),
  448.         0x1B8   => array(0x1B9),
  449.         0x1BC   => array(0x1BD),
  450.         0x1C4   => array(0x1C6),
  451.         0x1C5   => array(0x1C6),
  452.         0x1C7   => array(0x1C9),
  453.         0x1C8   => array(0x1C9),
  454.         0x1CA   => array(0x1CC),
  455.         0x1CB   => array(0x1CC),
  456.         0x1CD   => array(0x1CE),
  457.         0x1CF   => array(0x1D0),
  458.         0x1D1   => array(0x1D2),
  459.         0x1D3   => array(0x1D4),
  460.         0x1D5   => array(0x1D6),
  461.         0x1D7   => array(0x1D8),
  462.         0x1D9   => array(0x1DA),
  463.         0x1DB   => array(0x1DC),
  464.         0x1DE   => array(0x1DF),
  465.         0x1E0   => array(0x1E1),
  466.         0x1E2   => array(0x1E3),
  467.         0x1E4   => array(0x1E5),
  468.         0x1E6   => array(0x1E7),
  469.         0x1E8   => array(0x1E9),
  470.         0x1EA   => array(0x1EB),
  471.         0x1EC   => array(0x1ED),
  472.         0x1EE   => array(0x1EF),
  473.         0x1F0   => array(0x6A0x30C),
  474.         0x1F1   => array(0x1F3),
  475.         0x1F2   => array(0x1F3),
  476.         0x1F4   => array(0x1F5),
  477.         0x1F6   => array(0x195),
  478.         0x1F7   => array(0x1BF),
  479.         0x1F8   => array(0x1F9),
  480.         0x1FA   => array(0x1FB),
  481.         0x1FC   => array(0x1FD),
  482.         0x1FE   => array(0x1FF),
  483.         0x200   => array(0x201),
  484.         0x202   => array(0x203),
  485.         0x204   => array(0x205),
  486.         0x206   => array(0x207),
  487.         0x208   => array(0x209),
  488.         0x20A   => array(0x20B),
  489.         0x20C   => array(0x20D),
  490.         0x20E   => array(0x20F),
  491.         0x210   => array(0x211),
  492.         0x212   => array(0x213),
  493.         0x214   => array(0x215),
  494.         0x216   => array(0x217),
  495.         0x218   => array(0x219),
  496.         0x21A   => array(0x21B),
  497.         0x21C   => array(0x21D),
  498.         0x21E   => array(0x21F),
  499.         0x220   => array(0x19E),
  500.         0x222   => array(0x223),
  501.         0x224   => array(0x225),
  502.         0x226   => array(0x227),
  503.         0x228   => array(0x229),
  504.         0x22A   => array(0x22B),
  505.         0x22C   => array(0x22D),
  506.         0x22E   => array(0x22F),
  507.         0x230   => array(0x231),
  508.         0x232   => array(0x233),
  509.         0x345   => array(0x3B9),
  510.         0x37A   => array(0x200x3B9),
  511.         0x386   => array(0x3AC),
  512.         0x388   => array(0x3AD),
  513.         0x389   => array(0x3AE),
  514.         0x38A   => array(0x3AF),
  515.         0x38C   => array(0x3CC),
  516.         0x38E   => array(0x3CD),
  517.         0x38F   => array(0x3CE),
  518.         0x390   => array(0x3B90x3080x301),
  519.         0x391   => array(0x3B1),
  520.         0x392   => array(0x3B2),
  521.         0x393   => array(0x3B3),
  522.         0x394   => array(0x3B4),
  523.         0x395   => array(0x3B5),
  524.         0x396   => array(0x3B6),
  525.         0x397   => array(0x3B7),
  526.         0x398   => array(0x3B8),
  527.         0x399   => array(0x3B9),
  528.         0x39A   => array(0x3BA),
  529.         0x39B   => array(0x3BB),
  530.         0x39C   => array(0x3BC),
  531.         0x39D   => array(0x3BD),
  532.         0x39E   => array(0x3BE),
  533.         0x39F   => array(0x3BF),
  534.         0x3A0   => array(0x3C0),
  535.         0x3A1   => array(0x3C1),
  536.         0x3A3   => array(0x3C3),
  537.         0x3A4   => array(0x3C4),
  538.         0x3A5   => array(0x3C5),
  539.         0x3A6   => array(0x3C6),
  540.         0x3A7   => array(0x3C7),
  541.         0x3A8   => array(0x3C8),
  542.         0x3A9   => array(0x3C9),
  543.         0x3AA   => array(0x3CA),
  544.         0x3AB   => array(0x3CB),
  545.         0x3B0   => array(0x3C50x3080x301),
  546.         0x3C2   => array(0x3C3),
  547.         0x3D0   => array(0x3B2),
  548.         0x3D1   => array(0x3B8),
  549.         0x3D2   => array(0x3C5),
  550.         0x3D3   => array(0x3CD),
  551.         0x3D4   => array(0x3CB),
  552.         0x3D5   => array(0x3C6),
  553.         0x3D6   => array(0x3C0),
  554.         0x3D8   => array(0x3D9),
  555.         0x3DA   => array(0x3DB),
  556.         0x3DC   => array(0x3DD),
  557.         0x3DE   => array(0x3DF),
  558.         0x3E0   => array(0x3E1),
  559.         0x3E2   => array(0x3E3),
  560.         0x3E4   => array(0x3E5),
  561.         0x3E6   => array(0x3E7),
  562.         0x3E8   => array(0x3E9),
  563.         0x3EA   => array(0x3EB),
  564.         0x3EC   => array(0x3ED),
  565.         0x3EE   => array(0x3EF),
  566.         0x3F0   => array(0x3BA),
  567.         0x3F1   => array(0x3C1),
  568.         0x3F2   => array(0x3C3),
  569.         0x3F4   => array(0x3B8),
  570.         0x3F5   => array(0x3B5),
  571.         0x400   => array(0x450),
  572.         0x401   => array(0x451),
  573.         0x402   => array(0x452),
  574.         0x403   => array(0x453),
  575.         0x404   => array(0x454),
  576.         0x405   => array(0x455),
  577.         0x406   => array(0x456),
  578.         0x407   => array(0x457),
  579.         0x408   => array(0x458),
  580.         0x409   => array(0x459),
  581.         0x40A   => array(0x45A),
  582.         0x40B   => array(0x45B),
  583.         0x40C   => array(0x45C),
  584.         0x40D   => array(0x45D),
  585.         0x40E   => array(0x45E),
  586.         0x40F   => array(0x45F),
  587.         0x410   => array(0x430),
  588.         0x411   => array(0x431),
  589.         0x412   => array(0x432),
  590.         0x413   => array(0x433),
  591.         0x414   => array(0x434),
  592.         0x415   => array(0x435),
  593.         0x416   => array(0x436),
  594.         0x417   => array(0x437),
  595.         0x418   => array(0x438),
  596.         0x419   => array(0x439),
  597.         0x41A   => array(0x43A),
  598.         0x41B   => array(0x43B),
  599.         0x41C   => array(0x43C),
  600.         0x41D   => array(0x43D),
  601.         0x41E   => array(0x43E),
  602.         0x41F   => array(0x43F),
  603.         0x420   => array(0x440),
  604.         0x421   => array(0x441),
  605.         0x422   => array(0x442),
  606.         0x423   => array(0x443),
  607.         0x424   => array(0x444),
  608.         0x425   => array(0x445),
  609.         0x426   => array(0x446),
  610.         0x427   => array(0x447),
  611.         0x428   => array(0x448),
  612.         0x429   => array(0x449),
  613.         0x42A   => array(0x44A),
  614.         0x42B   => array(0x44B),
  615.         0x42C   => array(0x44C),
  616.         0x42D   => array(0x44D),
  617.         0x42E   => array(0x44E),
  618.         0x42F   => array(0x44F),
  619.         0x460   => array(0x461),
  620.         0x462   => array(0x463),
  621.         0x464   => array(0x465),
  622.         0x466   => array(0x467),
  623.         0x468   => array(0x469),
  624.         0x46A   => array(0x46B),
  625.         0x46C   => array(0x46D),
  626.         0x46E   => array(0x46F),
  627.         0x470   => array(0x471),
  628.         0x472   => array(0x473),
  629.         0x474   => array(0x475),
  630.         0x476   => array(0x477),
  631.         0x478   => array(0x479),
  632.         0x47A   => array(0x47B),
  633.         0x47C   => array(0x47D),
  634.         0x47E   => array(0x47F),
  635.         0x480   => array(0x481),
  636.         0x48A   => array(0x48B),
  637.         0x48C   => array(0x48D),
  638.         0x48E   => array(0x48F),
  639.         0x490   => array(0x491),
  640.         0x492   => array(0x493),
  641.         0x494   => array(0x495),
  642.         0x496   => array(0x497),
  643.         0x498   => array(0x499),
  644.         0x49A   => array(0x49B),
  645.         0x49C   => array(0x49D),
  646.         0x49E   => array(0x49F),
  647.         0x4A0   => array(0x4A1),
  648.         0x4A2   => array(0x4A3),
  649.         0x4A4   => array(0x4A5),
  650.         0x4A6   => array(0x4A7),
  651.         0x4A8   => array(0x4A9),
  652.         0x4AA   => array(0x4AB),
  653.         0x4AC   => array(0x4AD),
  654.         0x4AE   => array(0x4AF),
  655.         0x4B0   => array(0x4B1),
  656.         0x4B2   => array(0x4B3),
  657.         0x4B4   => array(0x4B5),
  658.         0x4B6   => array(0x4B7),
  659.         0x4B8   => array(0x4B9),
  660.         0x4BA   => array(0x4BB),
  661.         0x4BC   => array(0x4BD),
  662.         0x4BE   => array(0x4BF),
  663.         0x4C1   => array(0x4C2),
  664.         0x4C3   => array(0x4C4),
  665.         0x4C5   => array(0x4C6),
  666.         0x4C7   => array(0x4C8),
  667.         0x4C9   => array(0x4CA),
  668.         0x4CB   => array(0x4CC),
  669.         0x4CD   => array(0x4CE),
  670.         0x4D0   => array(0x4D1),
  671.         0x4D2   => array(0x4D3),
  672.         0x4D4   => array(0x4D5),
  673.         0x4D6   => array(0x4D7),
  674.         0x4D8   => array(0x4D9),
  675.         0x4DA   => array(0x4DB),
  676.         0x4DC   => array(0x4DD),
  677.         0x4DE   => array(0x4DF),
  678.         0x4E0   => array(0x4E1),
  679.         0x4E2   => array(0x4E3),
  680.         0x4E4   => array(0x4E5),
  681.         0x4E6   => array(0x4E7),
  682.         0x4E8   => array(0x4E9),
  683.         0x4EA   => array(0x4EB),
  684.         0x4EC   => array(0x4ED),
  685.         0x4EE   => array(0x4EF),
  686.         0x4F0   => array(0x4F1),
  687.         0x4F2   => array(0x4F3),
  688.         0x4F4   => array(0x4F5),
  689.         0x4F8   => array(0x4F9),
  690.         0x500   => array(0x501),
  691.         0x502   => array(0x503),
  692.         0x504   => array(0x505),
  693.         0x506   => array(0x507),
  694.         0x508   => array(0x509),
  695.         0x50A   => array(0x50B),
  696.         0x50C   => array(0x50D),
  697.         0x50E   => array(0x50F),
  698.         0x531   => array(0x561),
  699.         0x532   => array(0x562),
  700.         0x533   => array(0x563),
  701.         0x534   => array(0x564),
  702.         0x535   => array(0x565),
  703.         0x536   => array(0x566),
  704.         0x537   => array(0x567),
  705.         0x538   => array(0x568),
  706.         0x539   => array(0x569),
  707.         0x53A   => array(0x56A),
  708.         0x53B   => array(0x56B),
  709.         0x53C   => array(0x56C),
  710.         0x53D   => array(0x56D),
  711.         0x53E   => array(0x56E),
  712.         0x53F   => array(0x56F),
  713.         0x540   => array(0x570),
  714.         0x541   => array(0x571),
  715.         0x542   => array(0x572),
  716.         0x543   => array(0x573),
  717.         0x544   => array(0x574),
  718.         0x545   => array(0x575),
  719.         0x546   => array(0x576),
  720.         0x547   => array(0x577),
  721.         0x548   => array(0x578),
  722.         0x549   => array(0x579),
  723.         0x54A   => array(0x57A),
  724.         0x54B   => array(0x57B),
  725.         0x54C   => array(0x57C),
  726.         0x54D   => array(0x57D),
  727.         0x54E   => array(0x57E),
  728.         0x54F   => array(0x57F),
  729.         0x550   => array(0x580),
  730.         0x551   => array(0x581),
  731.         0x552   => array(0x582),
  732.         0x553   => array(0x583),
  733.         0x554   => array(0x584),
  734.         0x555   => array(0x585),
  735.         0x556   => array(0x586),
  736.         0x587   => array(0x5650x582),
  737.         0x1E00  => array(0x1E01),
  738.         0x1E02  => array(0x1E03),
  739.         0x1E04  => array(0x1E05),
  740.         0x1E06  => array(0x1E07),
  741.         0x1E08  => array(0x1E09),
  742.         0x1E0A  => array(0x1E0B),
  743.         0x1E0C  => array(0x1E0D),
  744.         0x1E0E  => array(0x1E0F),
  745.         0x1E10  => array(0x1E11),
  746.         0x1E12  => array(0x1E13),
  747.         0x1E14  => array(0x1E15),
  748.         0x1E16  => array(0x1E17),
  749.         0x1E18  => array(0x1E19),
  750.         0x1E1A  => array(0x1E1B),
  751.         0x1E1C  => array(0x1E1D),
  752.         0x1E1E  => array(0x1E1F),
  753.         0x1E20  => array(0x1E21),
  754.         0x1E22  => array(0x1E23),
  755.         0x1E24  => array(0x1E25),
  756.         0x1E26  => array(0x1E27),
  757.         0x1E28  => array(0x1E29),
  758.         0x1E2A  => array(0x1E2B),
  759.         0x1E2C  => array(0x1E2D),
  760.         0x1E2E  => array(0x1E2F),
  761.         0x1E30  => array(0x1E31),
  762.         0x1E32  => array(0x1E33),
  763.         0x1E34  => array(0x1E35),
  764.         0x1E36  => array(0x1E37),
  765.         0x1E38  => array(0x1E39),
  766.         0x1E3A  => array(0x1E3B),
  767.         0x1E3C  => array(0x1E3D),
  768.         0x1E3E  => array(0x1E3F),
  769.         0x1E40  => array(0x1E41),
  770.         0x1E42  => array(0x1E43),
  771.         0x1E44  => array(0x1E45),
  772.         0x1E46  => array(0x1E47),
  773.         0x1E48  => array(0x1E49),
  774.         0x1E4A  => array(0x1E4B),
  775.         0x1E4C  => array(0x1E4D),
  776.         0x1E4E  => array(0x1E4F),
  777.         0x1E50  => array(0x1E51),
  778.         0x1E52  => array(0x1E53),
  779.         0x1E54  => array(0x1E55),
  780.         0x1E56  => array(0x1E57),
  781.         0x1E58  => array(0x1E59),
  782.         0x1E5A  => array(0x1E5B),
  783.         0x1E5C  => array(0x1E5D),
  784.         0x1E5E  => array(0x1E5F),
  785.         0x1E60  => array(0x1E61),
  786.         0x1E62  => array(0x1E63),
  787.         0x1E64  => array(0x1E65),
  788.         0x1E66  => array(0x1E67),
  789.         0x1E68  => array(0x1E69),
  790.         0x1E6A  => array(0x1E6B),
  791.         0x1E6C  => array(0x1E6D),
  792.         0x1E6E  => array(0x1E6F),
  793.         0x1E70  => array(0x1E71),
  794.         0x1E72  => array(0x1E73),
  795.         0x1E74  => array(0x1E75),
  796.         0x1E76  => array(0x1E77),
  797.         0x1E78  => array(0x1E79),
  798.         0x1E7A  => array(0x1E7B),
  799.         0x1E7C  => array(0x1E7D),
  800.         0x1E7E  => array(0x1E7F),
  801.         0x1E80  => array(0x1E81),
  802.         0x1E82  => array(0x1E83),
  803.         0x1E84  => array(0x1E85),
  804.         0x1E86  => array(0x1E87),
  805.         0x1E88  => array(0x1E89),
  806.         0x1E8A  => array(0x1E8B),
  807.         0x1E8C  => array(0x1E8D),
  808.         0x1E8E  => array(0x1E8F),
  809.         0x1E90  => array(0x1E91),
  810.         0x1E92  => array(0x1E93),
  811.         0x1E94  => array(0x1E95),
  812.         0x1E96  => array(0x680x331),
  813.         0x1E97  => array(0x740x308),
  814.         0x1E98  => array(0x770x30A),
  815.         0x1E99  => array(0x790x30A),
  816.         0x1E9A  => array(0x610x2BE),
  817.         0x1E9B  => array(0x1E61),
  818.         0x1EA0  => array(0x1EA1),
  819.         0x1EA2  => array(0x1EA3),
  820.         0x1EA4  => array(0x1EA5),
  821.         0x1EA6  => array(0x1EA7),
  822.         0x1EA8  => array(0x1EA9),
  823.         0x1EAA  => array(0x1EAB),
  824.         0x1EAC  => array(0x1EAD),
  825.         0x1EAE  => array(0x1EAF),
  826.         0x1EB0  => array(0x1EB1),
  827.         0x1EB2  => array(0x1EB3),
  828.         0x1EB4  => array(0x1EB5),
  829.         0x1EB6  => array(0x1EB7),
  830.         0x1EB8  => array(0x1EB9),
  831.         0x1EBA  => array(0x1EBB),
  832.         0x1EBC  => array(0x1EBD),
  833.         0x1EBE  => array(0x1EBF),
  834.         0x1EC0  => array(0x1EC1),
  835.         0x1EC2  => array(0x1EC3),
  836.         0x1EC4  => array(0x1EC5),
  837.         0x1EC6  => array(0x1EC7),
  838.         0x1EC8  => array(0x1EC9),
  839.         0x1ECA  => array(0x1ECB),
  840.         0x1ECC  => array(0x1ECD),
  841.         0x1ECE  => array(0x1ECF),
  842.         0x1ED0  => array(0x1ED1),
  843.         0x1ED2  => array(0x1ED3),
  844.         0x1ED4  => array(0x1ED5),
  845.         0x1ED6  => array(0x1ED7),
  846.         0x1ED8  => array(0x1ED9),
  847.         0x1EDA  => array(0x1EDB),
  848.         0x1EDC  => array(0x1EDD),
  849.         0x1EDE  => array(0x1EDF),
  850.         0x1EE0  => array(0x1EE1),
  851.         0x1EE2  => array(0x1EE3),
  852.         0x1EE4  => array(0x1EE5),
  853.         0x1EE6  => array(0x1EE7),
  854.         0x1EE8  => array(0x1EE9),
  855.         0x1EEA  => array(0x1EEB),
  856.         0x1EEC  => array(0x1EED),
  857.         0x1EEE  => array(0x1EEF),
  858.         0x1EF0  => array(0x1EF1),
  859.         0x1EF2  => array(0x1EF3),
  860.         0x1EF4  => array(0x1EF5),
  861.         0x1EF6  => array(0x1EF7),
  862.         0x1EF8  => array(0x1EF9),
  863.         0x1F08  => array(0x1F00),
  864.         0x1F09  => array(0x1F01),
  865.         0x1F0A  => array(0x1F02),
  866.         0x1F0B  => array(0x1F03),
  867.         0x1F0C  => array(0x1F04),
  868.         0x1F0D  => array(0x1F05),
  869.         0x1F0E  => array(0x1F06),
  870.         0x1F0F  => array(0x1F07),
  871.         0x1F18  => array(0x1F10),
  872.         0x1F19  => array(0x1F11),
  873.         0x1F1A  => array(0x1F12),
  874.         0x1F1B  => array(0x1F13),
  875.         0x1F1C  => array(0x1F14),
  876.         0x1F1D  => array(0x1F15),
  877.         0x1F28  => array(0x1F20),
  878.         0x1F29  => array(0x1F21),
  879.         0x1F2A  => array(0x1F22),
  880.         0x1F2B  => array(0x1F23),
  881.         0x1F2C  => array(0x1F24),
  882.         0x1F2D  => array(0x1F25),
  883.         0x1F2E  => array(0x1F26),
  884.         0x1F2F  => array(0x1F27),
  885.         0x1F38  => array(0x1F30),
  886.         0x1F39  => array(0x1F31),
  887.         0x1F3A  => array(0x1F32),
  888.         0x1F3B  => array(0x1F33),
  889.         0x1F3C  => array(0x1F34),
  890.         0x1F3D  => array(0x1F35),
  891.         0x1F3E  => array(0x1F36),
  892.         0x1F3F  => array(0x1F37),
  893.         0x1F48  => array(0x1F40),
  894.         0x1F49  => array(0x1F41),
  895.         0x1F4A  => array(0x1F42),
  896.         0x1F4B  => array(0x1F43),
  897.         0x1F4C  => array(0x1F44),
  898.         0x1F4D  => array(0x1F45),
  899.         0x1F50  => array(0x3C50x313),
  900.         0x1F52  => array(0x3C50x3130x300),
  901.         0x1F54  => array(0x3C50x3130x301),
  902.         0x1F56  => array(0x3C50x3130x342),
  903.         0x1F59  => array(0x1F51),
  904.         0x1F5B  => array(0x1F53),
  905.         0x1F5D  => array(0x1F55),
  906.         0x1F5F  => array(0x1F57),
  907.         0x1F68  => array(0x1F60),
  908.         0x1F69  => array(0x1F61),
  909.         0x1F6A  => array(0x1F62),
  910.         0x1F6B  => array(0x1F63),
  911.         0x1F6C  => array(0x1F64),
  912.         0x1F6D  => array(0x1F65),
  913.         0x1F6E  => array(0x1F66),
  914.         0x1F6F  => array(0x1F67),
  915.         0x1F80  => array(0x1F000x3B9),
  916.         0x1F81  => array(0x1F010x3B9),
  917.         0x1F82  => array(0x1F020x3B9),
  918.         0x1F83  => array(0x1F030x3B9),
  919.         0x1F84  => array(0x1F040x3B9),
  920.         0x1F85  => array(0x1F050x3B9),
  921.         0x1F86  => array(0x1F060x3B9),
  922.         0x1F87  => array(0x1F070x3B9),
  923.         0x1F88  => array(0x1F000x3B9),
  924.         0x1F89  => array(0x1F010x3B9),
  925.         0x1F8A  => array(0x1F020x3B9),
  926.         0x1F8B  => array(0x1F030x3B9),
  927.         0x1F8C  => array(0x1F040x3B9),
  928.         0x1F8D  => array(0x1F050x3B9),
  929.         0x1F8E  => array(0x1F060x3B9),
  930.         0x1F8F  => array(0x1F070x3B9),
  931.         0x1F90  => array(0x1F200x3B9),
  932.         0x1F91  => array(0x1F210x3B9),
  933.         0x1F92  => array(0x1F220x3B9),
  934.         0x1F93  => array(0x1F230x3B9),
  935.         0x1F94  => array(0x1F240x3B9),
  936.         0x1F95  => array(0x1F250x3B9),
  937.         0x1F96  => array(0x1F260x3B9),
  938.         0x1F97  => array(0x1F270x3B9),
  939.         0x1F98  => array(0x1F200x3B9),
  940.         0x1F99  => array(0x1F210x3B9),
  941.         0x1F9A  => array(0x1F220x3B9),
  942.         0x1F9B  => array(0x1F230x3B9),
  943.         0x1F9C  => array(0x1F240x3B9),
  944.         0x1F9D  => array(0x1F250x3B9),
  945.         0x1F9E  => array(0x1F260x3B9),
  946.         0x1F9F  => array(0x1F270x3B9),
  947.         0x1FA0  => array(0x1F600x3B9),
  948.         0x1FA1  => array(0x1F610x3B9),
  949.         0x1FA2  => array(0x1F620x3B9),
  950.         0x1FA3  => array(0x1F630x3B9),
  951.         0x1FA4  => array(0x1F640x3B9),
  952.         0x1FA5  => array(0x1F650x3B9),
  953.         0x1FA6  => array(0x1F660x3B9),
  954.         0x1FA7  => array(0x1F670x3B9),
  955.         0x1FA8  => array(0x1F600x3B9),
  956.         0x1FA9  => array(0x1F610x3B9),
  957.         0x1FAA  => array(0x1F620x3B9),
  958.         0x1FAB  => array(0x1F630x3B9),
  959.         0x1FAC  => array(0x1F640x3B9),
  960.         0x1FAD  => array(0x1F650x3B9),
  961.         0x1FAE  => array(0x1F660x3B9),
  962.         0x1FAF  => array(0x1F670x3B9),
  963.         0x1FB2  => array(0x1F700x3B9),
  964.         0x1FB3  => array(0x3B10x3B9),
  965.         0x1FB4  => array(0x3AC0x3B9),
  966.         0x1FB6  => array(0x3B10x342),
  967.         0x1FB7  => array(0x3B10x3420x3B9),
  968.         0x1FB8  => array(0x1FB0),
  969.         0x1FB9  => array(0x1FB1),
  970.         0x1FBA  => array(0x1F70),
  971.         0x1FBB  => array(0x1F71),
  972.         0x1FBC  => array(0x3B10x3B9),
  973.         0x1FBE  => array(0x3B9),
  974.         0x1FC2  => array(0x1F740x3B9),
  975.         0x1FC3  => array(0x3B70x3B9),
  976.         0x1FC4  => array(0x3AE0x3B9),
  977.         0x1FC6  => array(0x3B70x342),
  978.         0x1FC7  => array(0x3B70x3420x3B9),
  979.         0x1FC8  => array(0x1F72),
  980.         0x1FC9  => array(0x1F73),
  981.         0x1FCA  => array(0x1F74),
  982.         0x1FCB  => array(0x1F75),
  983.         0x1FCC  => array(0x3B70x3B9),
  984.         0x1FD2  => array(0x3B90x3080x300),
  985.         0x1FD3  => array(0x3B90x3080x301),
  986.         0x1FD6  => array(0x3B90x342),
  987.         0x1FD7  => array(0x3B90x3080x342),
  988.         0x1FD8  => array(0x1FD0),
  989.         0x1FD9  => array(0x1FD1),
  990.         0x1FDA  => array(0x1F76),
  991.         0x1FDB  => array(0x1F77),
  992.         0x1FE2  => array(0x3C50x3080x300),
  993.         0x1FE3  => array(0x3C50x3080x301),
  994.         0x1FE4  => array(0x3C10x313),
  995.         0x1FE6  => array(0x3C50x342),
  996.         0x1FE7  => array(0x3C50x3080x342),
  997.         0x1FE8  => array(0x1FE0),
  998.         0x1FE9  => array(0x1FE1),
  999.         0x1FEA  => array(0x1F7A),
  1000.         0x1FEB  => array(0x1F7B),
  1001.         0x1FEC  => array(0x1FE5),
  1002.         0x1FF2  => array(0x1F7C0x3B9),
  1003.         0x1FF3  => array(0x3C90x3B9),
  1004.         0x1FF4  => array(0x3CE0x3B9),
  1005.         0x1FF6  => array(0x3C90x342),
  1006.         0x1FF7  => array(0x3C90x3420x3B9),
  1007.         0x1FF8  => array(0x1F78),
  1008.         0x1FF9  => array(0x1F79),
  1009.         0x1FFA  => array(0x1F7C),
  1010.         0x1FFB  => array(0x1F7D),
  1011.         0x1FFC  => array(0x3C90x3B9),
  1012.         0x20A8  => array(0x720x73),
  1013.         0x2102  => array(0x63),
  1014.         0x2103  => array(0xB00x63),
  1015.         0x2107  => array(0x25B),
  1016.         0x2109  => array(0xB00x66),
  1017.         0x210B  => array(0x68),
  1018.         0x210C  => array(0x68),
  1019.         0x210D  => array(0x68),
  1020.         0x2110  => array(0x69),
  1021.         0x2111  => array(0x69),
  1022.         0x2112  => array(0x6C),
  1023.         0x2115  => array(0x6E),
  1024.         0x2116  => array(0x6E0x6F),
  1025.         0x2119  => array(0x70),
  1026.         0x211A  => array(0x71),
  1027.         0x211B  => array(0x72),
  1028.         0x211C  => array(0x72),
  1029.         0x211D  => array(0x72),
  1030.         0x2120  => array(0x730x6D),
  1031.         0x2121  => array(0x740x650x6C),
  1032.         0x2122  => array(0x740x6D),
  1033.         0x2124  => array(0x7A),
  1034.         0x2126  => array(0x3C9),
  1035.         0x2128  => array(0x7A),
  1036.         0x212A  => array(0x6B),
  1037.         0x212B  => array(0xE5),
  1038.         0x212C  => array(0x62),
  1039.         0x212D  => array(0x63),
  1040.         0x2130  => array(0x65),
  1041.         0x2131  => array(0x66),
  1042.         0x2133  => array(0x6D),
  1043.         0x213E  => array(0x3B3),
  1044.         0x213F  => array(0x3C0),
  1045.         0x2145  => array(0x64),
  1046.         0x2160  => array(0x2170),
  1047.         0x2161  => array(0x2171),
  1048.         0x2162  => array(0x2172),
  1049.         0x2163  => array(0x2173),
  1050.         0x2164  => array(0x2174),
  1051.         0x2165  => array(0x2175),
  1052.         0x2166  => array(0x2176),
  1053.         0x2167  => array(0x2177),
  1054.         0x2168  => array(0x2178),
  1055.         0x2169  => array(0x2179),
  1056.         0x216A  => array(0x217A),
  1057.         0x216B  => array(0x217B),
  1058.         0x216C  => array(0x217C),
  1059.         0x216D  => array(0x217D),
  1060.         0x216E  => array(0x217E),
  1061.         0x216F  => array(0x217F),
  1062.         0x24B6  => array(0x24D0),
  1063.         0x24B7  => array(0x24D1),
  1064.         0x24B8  => array(0x24D2),
  1065.         0x24B9  => array(0x24D3),
  1066.         0x24BA  => array(0x24D4),
  1067.         0x24BB  => array(0x24D5),
  1068.         0x24BC  => array(0x24D6),
  1069.         0x24BD  => array(0x24D7),
  1070.         0x24BE  => array(0x24D8),
  1071.         0x24BF  => array(0x24D9),
  1072.         0x24C0  => array(0x24DA),
  1073.         0x24C1  => array(0x24DB),
  1074.         0x24C2  => array(0x24DC),
  1075.         0x24C3  => array(0x24DD),
  1076.         0x24C4  => array(0x24DE),
  1077.         0x24C5  => array(0x24DF),
  1078.         0x24C6  => array(0x24E0),
  1079.         0x24C7  => array(0x24E1),
  1080.         0x24C8  => array(0x24E2),
  1081.         0x24C9  => array(0x24E3),
  1082.         0x24CA  => array(0x24E4),
  1083.         0x24CB  => array(0x24E5),
  1084.         0x24CC  => array(0x24E6),
  1085.         0x24CD  => array(0x24E7),
  1086.         0x24CE  => array(0x24E8),
  1087.         0x24CF  => array(0x24E9),
  1088.         0x3371  => array(0x680x700x61),
  1089.         0x3373  => array(0x610x75),
  1090.         0x3375  => array(0x6F0x76),
  1091.         0x3380  => array(0x700x61),
  1092.         0x3381  => array(0x6E0x61),
  1093.         0x3382  => array(0x3BC0x61),
  1094.         0x3383  => array(0x6D0x61),
  1095.         0x3384  => array(0x6B0x61),
  1096.         0x3385  => array(0x6B0x62),
  1097.         0x3386  => array(0x6D0x62),
  1098.         0x3387  => array(0x670x62),
  1099.         0x338A  => array(0x700x66),
  1100.         0x338B  => array(0x6E0x66),
  1101.         0x338C  => array(0x3BC0x66),
  1102.         0x3390  => array(0x680x7A),
  1103.         0x3391  => array(0x6B0x680x7A),
  1104.         0x3392  => array(0x6D0x680x7A),
  1105.         0x3393  => array(0x670x680x7A),
  1106.         0x3394  => array(0x740x680x7A),
  1107.         0x33A9  => array(0x700x61),
  1108.         0x33AA  => array(0x6B0x700x61),
  1109.         0x33AB  => array(0x6D0x700x61),
  1110.         0x33AC  => array(0x670x700x61),
  1111.         0x33B4  => array(0x700x76),
  1112.         0x33B5  => array(0x6E0x76),
  1113.         0x33B6  => array(0x3BC0x76),
  1114.         0x33B7  => array(0x6D0x76),
  1115.         0x33B8  => array(0x6B0x76),
  1116.         0x33B9  => array(0x6D0x76),
  1117.         0x33BA  => array(0x700x77),
  1118.         0x33BB  => array(0x6E0x77),
  1119.         0x33BC  => array(0x3BC0x77),
  1120.         0x33BD  => array(0x6D0x77),
  1121.         0x33BE  => array(0x6B0x77),
  1122.         0x33BF  => array(0x6D0x77),
  1123.         0x33C0  => array(0x6B0x3C9),
  1124.         0x33C1  => array(0x6D0x3C9)/*
  1125.         0x33C2  => array(0x61, 0x2E, 0x6D, 0x2E), */
  1126.         0x33C3  => array(0x620x71),
  1127.         0x33C6  => array(0x630x22150x6B0x67),
  1128.         0x33C7  => array(0x630x6F0x2E),
  1129.         0x33C8  => array(0x640x62),
  1130.         0x33C9  => array(0x670x79),
  1131.         0x33CB  => array(0x680x70),
  1132.         0x33CD  => array(0x6B0x6B),
  1133.         0x33CE  => array(0x6B0x6D),
  1134.         0x33D7  => array(0x700x68),
  1135.         0x33D9  => array(0x700x700x6D),
  1136.         0x33DA  => array(0x700x72),
  1137.         0x33DC  => array(0x730x76),
  1138.         0x33DD  => array(0x770x62),
  1139.         0xFB00  => array(0x660x66),
  1140.         0xFB01  => array(0x660x69),
  1141.         0xFB02  => array(0x660x6C),
  1142.         0xFB03  => array(0x660x660x69),
  1143.         0xFB04  => array(0x660x660x6C),
  1144.         0xFB05  => array(0x730x74),
  1145.         0xFB06  => array(0x730x74),
  1146.         0xFB13  => array(0x5740x576),
  1147.         0xFB14  => array(0x5740x565),
  1148.         0xFB15  => array(0x5740x56B),
  1149.         0xFB16  => array(0x57E0x576),
  1150.         0xFB17  => array(0x5740x56D),
  1151.         0xFF21  => array(0xFF41),
  1152.         0xFF22  => array(0xFF42),
  1153.         0xFF23  => array(0xFF43),
  1154.         0xFF24  => array(0xFF44),
  1155.         0xFF25  => array(0xFF45),
  1156.         0xFF26  => array(0xFF46),
  1157.         0xFF27  => array(0xFF47),
  1158.         0xFF28  => array(0xFF48),
  1159.         0xFF29  => array(0xFF49),
  1160.         0xFF2A  => array(0xFF4A),
  1161.         0xFF2B  => array(0xFF4B),
  1162.         0xFF2C  => array(0xFF4C),
  1163.         0xFF2D  => array(0xFF4D),
  1164.         0xFF2E  => array(0xFF4E),
  1165.         0xFF2F  => array(0xFF4F),
  1166.         0xFF30  => array(0xFF50),
  1167.         0xFF31  => array(0xFF51),
  1168.         0xFF32  => array(0xFF52),
  1169.         0xFF33  => array(0xFF53),
  1170.         0xFF34  => array(0xFF54),
  1171.         0xFF35  => array(0xFF55),
  1172.         0xFF36  => array(0xFF56),
  1173.         0xFF37  => array(0xFF57),
  1174.         0xFF38  => array(0xFF58),
  1175.         0xFF39  => array(0xFF59),
  1176.         0xFF3A  => array(0xFF5A),
  1177.         0x10400 => array(0x10428),
  1178.         0x10401 => array(0x10429),
  1179.         0x10402 => array(0x1042A),
  1180.         0x10403 => array(0x1042B),
  1181.         0x10404 => array(0x1042C),
  1182.         0x10405 => array(0x1042D),
  1183.         0x10406 => array(0x1042E),
  1184.         0x10407 => array(0x1042F),
  1185.         0x10408 => array(0x10430),
  1186.         0x10409 => array(0x10431),
  1187.         0x1040A => array(0x10432),
  1188.         0x1040B => array(0x10433),
  1189.         0x1040C => array(0x10434),
  1190.         0x1040D => array(0x10435),
  1191.         0x1040E => array(0x10436),
  1192.         0x1040F => array(0x10437),
  1193.         0x10410 => array(0x10438),
  1194.         0x10411 => array(0x10439),
  1195.         0x10412 => array(0x1043A),
  1196.         0x10413 => array(0x1043B),
  1197.         0x10414 => array(0x1043C),
  1198.         0x10415 => array(0x1043D),
  1199.         0x10416 => array(0x1043E),
  1200.         0x10417 => array(0x1043F),
  1201.         0x10418 => array(0x10440),
  1202.         0x10419 => array(0x10441),
  1203.         0x1041A => array(0x10442),
  1204.         0x1041B => array(0x10443),
  1205.         0x1041C => array(0x10444),
  1206.         0x1041D => array(0x10445),
  1207.         0x1041E => array(0x10446),
  1208.         0x1041F => array(0x10447),
  1209.         0x10420 => array(0x10448),
  1210.         0x10421 => array(0x10449),
  1211.         0x10422 => array(0x1044A),
  1212.         0x10423 => array(0x1044B),
  1213.         0x10424 => array(0x1044C),
  1214.         0x10425 => array(0x1044D),
  1215.         0x1D400 => array(0x61),
  1216.         0x1D401 => array(0x62),
  1217.         0x1D402 => array(0x63),
  1218.         0x1D403 => array(0x64),
  1219.         0x1D404 => array(0x65),
  1220.         0x1D405 => array(0x66),
  1221.         0x1D406 => array(0x67),
  1222.         0x1D407 => array(0x68),
  1223.         0x1D408 => array(0x69),
  1224.         0x1D409 => array(0x6A),
  1225.         0x1D40A => array(0x6B),
  1226.         0x1D40B => array(0x6C),
  1227.         0x1D40C => array(0x6D),
  1228.         0x1D40D => array(0x6E),
  1229.         0x1D40E => array(0x6F),
  1230.         0x1D40F => array(0x70),
  1231.         0x1D410 => array(0x71),
  1232.         0x1D411 => array(0x72),
  1233.         0x1D412 => array(0x73),
  1234.         0x1D413 => array(0x74),
  1235.         0x1D414 => array(0x75),
  1236.         0x1D415 => array(0x76),
  1237.         0x1D416 => array(0x77),
  1238.         0x1D417 => array(0x78),
  1239.         0x1D418 => array(0x79),
  1240.         0x1D419 => array(0x7A),
  1241.         0x1D434 => array(0x61),
  1242.         0x1D435 => array(0x62),
  1243.         0x1D436 => array(0x63),
  1244.         0x1D437 => array(0x64),
  1245.         0x1D438 => array(0x65),
  1246.         0x1D439 => array(0x66),
  1247.         0x1D43A => array(0x67),
  1248.         0x1D43B => array(0x68),
  1249.         0x1D43C => array(0x69),
  1250.         0x1D43D => array(0x6A),
  1251.         0x1D43E => array(0x6B),
  1252.         0x1D43F => array(0x6C),
  1253.         0x1D440 => array(0x6D),
  1254.         0x1D441 => array(0x6E),
  1255.         0x1D442 => array(0x6F),
  1256.         0x1D443 => array(0x70),
  1257.         0x1D444 => array(0x71),
  1258.         0x1D445 => array(0x72),
  1259.         0x1D446 => array(0x73),
  1260.         0x1D447 => array(0x74),
  1261.         0x1D448 => array(0x75),
  1262.         0x1D449 => array(0x76),
  1263.         0x1D44A => array(0x77),
  1264.         0x1D44B => array(0x78),
  1265.         0x1D44C => array(0x79),
  1266.         0x1D44D => array(0x7A),
  1267.         0x1D468 => array(0x61),
  1268.         0x1D469 => array(0x62),
  1269.         0x1D46A => array(0x63),
  1270.         0x1D46B => array(0x64),
  1271.         0x1D46C => array(0x65),
  1272.         0x1D46D => array(0x66),
  1273.         0x1D46E => array(0x67),
  1274.         0x1D46F => array(0x68),
  1275.         0x1D470 => array(0x69),
  1276.         0x1D471 => array(0x6A),
  1277.         0x1D472 => array(0x6B),
  1278.         0x1D473 => array(0x6C),
  1279.         0x1D474 => array(0x6D),
  1280.         0x1D475 => array(0x6E),
  1281.         0x1D476 => array(0x6F),
  1282.         0x1D477 => array(0x70),
  1283.         0x1D478 => array(0x71),
  1284.         0x1D479 => array(0x72),
  1285.         0x1D47A => array(0x73),
  1286.         0x1D47B => array(0x74),
  1287.         0x1D47C => array(0x75),
  1288.         0x1D47D => array(0x76),
  1289.         0x1D47E => array(0x77),
  1290.         0x1D47F => array(0x78),
  1291.         0x1D480 => array(0x79),
  1292.         0x1D481 => array(0x7A),
  1293.         0x1D49C => array(0x61),
  1294.         0x1D49E => array(0x63),
  1295.         0x1D49F => array(0x64),
  1296.         0x1D4A2 => array(0x67),
  1297.         0x1D4A5 => array(0x6A),
  1298.         0x1D4A6 => array(0x6B),
  1299.         0x1D4A9 => array(0x6E),
  1300.         0x1D4AA => array(0x6F),
  1301.         0x1D4AB => array(0x70),
  1302.         0x1D4AC => array(0x71),
  1303.         0x1D4AE => array(0x73),
  1304.         0x1D4AF => array(0x74),
  1305.         0x1D4B0 => array(0x75),
  1306.         0x1D4B1 => array(0x76),
  1307.         0x1D4B2 => array(0x77),
  1308.         0x1D4B3 => array(0x78),
  1309.         0x1D4B4 => array(0x79),
  1310.         0x1D4B5 => array(0x7A),
  1311.         0x1D4D0 => array(0x61),
  1312.         0x1D4D1 => array(0x62),
  1313.         0x1D4D2 => array(0x63),
  1314.         0x1D4D3 => array(0x64),
  1315.         0x1D4D4 => array(0x65),
  1316.         0x1D4D5 => array(0x66),
  1317.         0x1D4D6 => array(0x67),
  1318.         0x1D4D7 => array(0x68),
  1319.         0x1D4D8 => array(0x69),
  1320.         0x1D4D9 => array(0x6A),
  1321.         0x1D4DA => array(0x6B),
  1322.         0x1D4DB => array(0x6C),
  1323.         0x1D4DC => array(0x6D),
  1324.         0x1D4DD => array(0x6E),
  1325.         0x1D4DE => array(0x6F),
  1326.         0x1D4DF => array(0x70),
  1327.         0x1D4E0 => array(0x71),
  1328.         0x1D4E1 => array(0x72),
  1329.         0x1D4E2 => array(0x73),
  1330.         0x1D4E3 => array(0x74),
  1331.         0x1D4E4 => array(0x75),
  1332.         0x1D4E5 => array(0x76),
  1333.         0x1D4E6 => array(0x77),
  1334.         0x1D4E7 => array(0x78),
  1335.         0x1D4E8 => array(0x79),
  1336.         0x1D4E9 => array(0x7A),
  1337.         0x1D504 => array(0x61),
  1338.         0x1D505 => array(0x62),
  1339.         0x1D507 => array(0x64),
  1340.         0x1D508 => array(0x65),
  1341.         0x1D509 => array(0x66),
  1342.         0x1D50A => array(0x67),
  1343.         0x1D50D => array(0x6A),
  1344.         0x1D50E => array(0x6B),
  1345.         0x1D50F => array(0x6C),
  1346.         0x1D510 => array(0x6D),
  1347.         0x1D511 => array(0x6E),
  1348.         0x1D512 => array(0x6F),
  1349.         0x1D513 => array(0x70),
  1350.         0x1D514 => array(0x71),
  1351.         0x1D516 => array(0x73),
  1352.         0x1D517 => array(0x74),
  1353.         0x1D518 => array(0x75),
  1354.         0x1D519 => array(0x76),
  1355.         0x1D51A => array(0x77),
  1356.         0x1D51B => array(0x78),
  1357.         0x1D51C => array(0x79),
  1358.         0x1D538 => array(0x61),
  1359.         0x1D539 => array(0x62),
  1360.         0x1D53B => array(0x64),
  1361.         0x1D53C => array(0x65),
  1362.         0x1D53D => array(0x66),
  1363.         0x1D53E => array(0x67),
  1364.         0x1D540 => array(0x69),
  1365.         0x1D541 => array(0x6A),
  1366.         0x1D542 => array(0x6B),
  1367.         0x1D543 => array(0x6C),
  1368.         0x1D544 => array(0x6D),
  1369.         0x1D546 => array(0x6F),
  1370.         0x1D54A => array(0x73),
  1371.         0x1D54B => array(0x74),
  1372.         0x1D54C => array(0x75),
  1373.         0x1D54D => array(0x76),
  1374.         0x1D54E => array(0x77),
  1375.         0x1D54F => array(0x78),
  1376.         0x1D550 => array(0x79),
  1377.         0x1D56C => array(0x61),
  1378.         0x1D56D => array(0x62),
  1379.         0x1D56E => array(0x63),
  1380.         0x1D56F => array(0x64),
  1381.         0x1D570 => array(0x65),
  1382.         0x1D571 => array(0x66),
  1383.         0x1D572 => array(0x67),
  1384.         0x1D573 => array(0x68),
  1385.         0x1D574 => array(0x69),
  1386.         0x1D575 => array(0x6A),
  1387.         0x1D576 => array(0x6B),
  1388.         0x1D577 => array(0x6C),
  1389.         0x1D578 => array(0x6D),
  1390.         0x1D579 => array(0x6E),
  1391.         0x1D57A => array(0x6F),
  1392.         0x1D57B => array(0x70),
  1393.         0x1D57C => array(0x71),
  1394.         0x1D57D => array(0x72),
  1395.         0x1D57E => array(0x73),
  1396.         0x1D57F => array(0x74),
  1397.         0x1D580 => array(0x75),
  1398.         0x1D581 => array(0x76),
  1399.         0x1D582 => array(0x77),
  1400.         0x1D583 => array(0x78),
  1401.         0x1D584 => array(0x79),
  1402.         0x1D585 => array(0x7A),
  1403.         0x1D5A0 => array(0x61),
  1404.         0x1D5A1 => array(0x62),
  1405.         0x1D5A2 => array(0x63),
  1406.         0x1D5A3 => array(0x64),
  1407.         0x1D5A4 => array(0x65),
  1408.         0x1D5A5 => array(0x66),
  1409.         0x1D5A6 => array(0x67),
  1410.         0x1D5A7 => array(0x68),
  1411.         0x1D5A8 => array(0x69),
  1412.         0x1D5A9 => array(0x6A),
  1413.         0x1D5AA => array(0x6B),
  1414.         0x1D5AB => array(0x6C),
  1415.         0x1D5AC => array(0x6D),
  1416.         0x1D5AD => array(0x6E),
  1417.         0x1D5AE => array(0x6F),
  1418.         0x1D5AF => array(0x70),
  1419.         0x1D5B0 => array(0x71),
  1420.         0x1D5B1 => array(0x72),
  1421.         0x1D5B2 => array(0x73),
  1422.         0x1D5B3 => array(0x74),
  1423.         0x1D5B4 => array(0x75),
  1424.         0x1D5B5 => array(0x76),
  1425.         0x1D5B6 => array(0x77),
  1426.         0x1D5B7 => array(0x78),
  1427.         0x1D5B8 => array(0x79),
  1428.         0x1D5B9 => array(0x7A),
  1429.         0x1D5D4 => array(0x61),
  1430.         0x1D5D5 => array(0x62),
  1431.         0x1D5D6 => array(0x63),
  1432.         0x1D5D7 => array(0x64),
  1433.         0x1D5D8 => array(0x65),
  1434.         0x1D5D9 => array(0x66),
  1435.         0x1D5DA => array(0x67),
  1436.         0x1D5DB => array(0x68),
  1437.         0x1D5DC => array(0x69),
  1438.         0x1D5DD => array(0x6A),
  1439.         0x1D5DE => array(0x6B),
  1440.         0x1D5DF => array(0x6C),
  1441.         0x1D5E0 => array(0x6D),
  1442.         0x1D5E1 => array(0x6E),
  1443.         0x1D5E2 => array(0x6F),
  1444.         0x1D5E3 => array(0x70),
  1445.         0x1D5E4 => array(0x71),
  1446.         0x1D5E5 => array(0x72),
  1447.         0x1D5E6 => array(0x73),
  1448.         0x1D5E7 => array(0x74),
  1449.         0x1D5E8 => array(0x75),
  1450.         0x1D5E9 => array(0x76),
  1451.         0x1D5EA => array(0x77),
  1452.         0x1D5EB => array(0x78),
  1453.         0x1D5EC => array(0x79),
  1454.         0x1D5ED => array(0x7A),
  1455.         0x1D608 => array(0x61),
  1456.         0x1D609 => array(0x62),
  1457.         0x1D60A => array(0x63),
  1458.         0x1D60B => array(0x64),
  1459.         0x1D60C => array(0x65),
  1460.         0x1D60D => array(0x66),
  1461.         0x1D60E => array(0x67),
  1462.         0x1D60F => array(0x68),
  1463.         0x1D610 => array(0x69),
  1464.         0x1D611 => array(0x6A),
  1465.         0x1D612 => array(0x6B),
  1466.         0x1D613 => array(0x6C),
  1467.         0x1D614 => array(0x6D),
  1468.         0x1D615 => array(0x6E),
  1469.         0x1D616 => array(0x6F),
  1470.         0x1D617 => array(0x70),
  1471.         0x1D618 => array(0x71),
  1472.         0x1D619 => array(0x72),
  1473.         0x1D61A => array(0x73),
  1474.         0x1D61B => array(0x74),
  1475.         0x1D61C => array(0x75),
  1476.         0x1D61D => array(0x76),
  1477.         0x1D61E => array(0x77),
  1478.         0x1D61F => array(0x78),
  1479.         0x1D620 => array(0x79),
  1480.         0x1D621 => array(0x7A),
  1481.         0x1D63C => array(0x61),
  1482.         0x1D63D => array(0x62),
  1483.         0x1D63E => array(0x63),
  1484.         0x1D63F => array(0x64),
  1485.         0x1D640 => array(0x65),
  1486.         0x1D641 => array(0x66),
  1487.         0x1D642 => array(0x67),
  1488.         0x1D643 => array(0x68),
  1489.         0x1D644 => array(0x69),
  1490.         0x1D645 => array(0x6A),
  1491.         0x1D646 => array(0x6B),
  1492.         0x1D647 => array(0x6C),
  1493.         0x1D648 => array(0x6D),
  1494.         0x1D649 => array(0x6E),
  1495.         0x1D64A => array(0x6F),
  1496.         0x1D64B => array(0x70),
  1497.         0x1D64C => array(0x71),
  1498.         0x1D64D => array(0x72),
  1499.         0x1D64E => array(0x73),
  1500.         0x1D64F => array(0x74),
  1501.         0x1D650 => array(0x75),
  1502.         0x1D651 => array(0x76),
  1503.         0x1D652 => array(0x77),
  1504.         0x1D653 => array(0x78),
  1505.         0x1D654 => array(0x79),
  1506.         0x1D655 => array(0x7A),
  1507.         0x1D670 => array(0x61),
  1508.         0x1D671 => array(0x62),
  1509.         0x1D672 => array(0x63),
  1510.         0x1D673 => array(0x64),
  1511.         0x1D674 => array(0x65),
  1512.         0x1D675 => array(0x66),
  1513.         0x1D676 => array(0x67),
  1514.         0x1D677 => array(0x68),
  1515.         0x1D678 => array(0x69),
  1516.         0x1D679 => array(0x6A),
  1517.         0x1D67A => array(0x6B),
  1518.         0x1D67B => array(0x6C),
  1519.         0x1D67C => array(0x6D),
  1520.         0x1D67D => array(0x6E),
  1521.         0x1D67E => array(0x6F),
  1522.         0x1D67F => array(0x70),
  1523.         0x1D680 => array(0x71),
  1524.         0x1D681 => array(0x72),
  1525.         0x1D682 => array(0x73),
  1526.         0x1D683 => array(0x74),
  1527.         0x1D684 => array(0x75),
  1528.         0x1D685 => array(0x76),
  1529.         0x1D686 => array(0x77),
  1530.         0x1D687 => array(0x78),
  1531.         0x1D688 => array(0x79),
  1532.         0x1D689 => array(0x7A),
  1533.         0x1D6A8 => array(0x3B1),
  1534.         0x1D6A9 => array(0x3B2),
  1535.         0x1D6AA => array(0x3B3),
  1536.         0x1D6AB => array(0x3B4),
  1537.         0x1D6AC => array(0x3B5),
  1538.         0x1D6AD => array(0x3B6),
  1539.         0x1D6AE => array(0x3B7),
  1540.         0x1D6AF => array(0x3B8),
  1541.         0x1D6B0 => array(0x3B9),
  1542.         0x1D6B1 => array(0x3BA),
  1543.         0x1D6B2 => array(0x3BB),
  1544.         0x1D6B3 => array(0x3BC),
  1545.         0x1D6B4 => array(0x3BD),
  1546.         0x1D6B5 => array(0x3BE),
  1547.         0x1D6B6 => array(0x3BF),
  1548.         0x1D6B7 => array(0x3C0),
  1549.         0x1D6B8 => array(0x3C1),
  1550.         0x1D6B9 => array(0x3B8),
  1551.         0x1D6BA => array(0x3C3),
  1552.         0x1D6BB => array(0x3C4),
  1553.         0x1D6BC => array(0x3C5),
  1554.         0x1D6BD => array(0x3C6),
  1555.         0x1D6BE => array(0x3C7),
  1556.         0x1D6BF => array(0x3C8),
  1557.         0x1D6C0 => array(0x3C9),
  1558.         0x1D6D3 => array(0x3C3),
  1559.         0x1D6E2 => array(0x3B1),
  1560.         0x1D6E3 => array(0x3B2),
  1561.         0x1D6E4 => array(0x3B3),
  1562.         0x1D6E5 => array(0x3B4),
  1563.         0x1D6E6 => array(0x3B5),
  1564.         0x1D6E7 => array(0x3B6),
  1565.         0x1D6E8 => array(0x3B7),
  1566.         0x1D6E9 => array(0x3B8),
  1567.         0x1D6EA => array(0x3B9),
  1568.         0x1D6EB => array(0x3BA),
  1569.         0x1D6EC => array(0x3BB),
  1570.         0x1D6ED => array(0x3BC),
  1571.         0x1D6EE => array(0x3BD),
  1572.         0x1D6EF => array(0x3BE),
  1573.         0x1D6F0 => array(0x3BF),
  1574.         0x1D6F1 => array(0x3C0),
  1575.         0x1D6F2 => array(0x3C1),
  1576.         0x1D6F3 => array(0x3B8),
  1577.         0x1D6F4 => array(0x3C3),
  1578.         0x1D6F5 => array(0x3C4),
  1579.         0x1D6F6 => array(0x3C5),
  1580.         0x1D6F7 => array(0x3C6),
  1581.         0x1D6F8 => array(0x3C7),
  1582.         0x1D6F9 => array(0x3C8),
  1583.         0x1D6FA => array(0x3C9),
  1584.         0x1D70D => array(0x3C3),
  1585.         0x1D71C => array(0x3B1),
  1586.         0x1D71D => array(0x3B2),
  1587.         0x1D71E => array(0x3B3),
  1588.         0x1D71F => array(0x3B4),
  1589.         0x1D720 => array(0x3B5),
  1590.         0x1D721 => array(0x3B6),
  1591.         0x1D722 => array(0x3B7),
  1592.         0x1D723 => array(0x3B8),
  1593.         0x1D724 => array(0x3B9),
  1594.         0x1D725 => array(0x3BA),
  1595.         0x1D726 => array(0x3BB),
  1596.         0x1D727 => array(0x3BC),
  1597.         0x1D728 => array(0x3BD),
  1598.         0x1D729 => array(0x3BE),
  1599.         0x1D72A => array(0x3BF),
  1600.         0x1D72B => array(0x3C0),
  1601.         0x1D72C => array(0x3C1),
  1602.         0x1D72D => array(0x3B8),
  1603.         0x1D72E => array(0x3C3),
  1604.         0x1D72F => array(0x3C4),
  1605.         0x1D730 => array(0x3C5),
  1606.         0x1D731 => array(0x3C6),
  1607.         0x1D732 => array(0x3C7),
  1608.         0x1D733 => array(0x3C8),
  1609.         0x1D734 => array(0x3C9),
  1610.         0x1D747 => array(0x3C3),
  1611.         0x1D756 => array(0x3B1),
  1612.         0x1D757 => array(0x3B2),
  1613.         0x1D758 => array(0x3B3),
  1614.         0x1D759 => array(0x3B4),
  1615.         0x1D75A => array(0x3B5),
  1616.         0x1D75B => array(0x3B6),
  1617.         0x1D75C => array(0x3B7),
  1618.         0x1D75D => array(0x3B8),
  1619.         0x1D75E => array(0x3B9),
  1620.         0x1D75F => array(0x3BA),
  1621.         0x1D760 => array(0x3BB),
  1622.         0x1D761 => array(0x3BC),
  1623.         0x1D762 => array(0x3BD),
  1624.         0x1D763 => array(0x3BE),
  1625.         0x1D764 => array(0x3BF),
  1626.         0x1D765 => array(0x3C0),
  1627.         0x1D766 => array(0x3C1),
  1628.         0x1D767 => array(0x3B8),
  1629.         0x1D768 => array(0x3C3),
  1630.         0x1D769 => array(0x3C4),
  1631.         0x1D76A => array(0x3C5),
  1632.         0x1D76B => array(0x3C6),
  1633.         0x1D76C => array(0x3C7),
  1634.         0x1D76D => array(0x3C8),
  1635.         0x1D76E => array(0x3C9),
  1636.         0x1D781 => array(0x3C3),
  1637.         0x1D790 => array(0x3B1),
  1638.         0x1D791 => array(0x3B2),
  1639.         0x1D792 => array(0x3B3),
  1640.         0x1D793 => array(0x3B4),
  1641.         0x1D794 => array(0x3B5),
  1642.         0x1D795 => array(0x3B6),
  1643.         0x1D796 => array(0x3B7),
  1644.         0x1D797 => array(0x3B8),
  1645.         0x1D798 => array(0x3B9),
  1646.         0x1D799 => array(0x3BA),
  1647.         0x1D79A => array(0x3BB),
  1648.         0x1D79B => array(0x3BC),
  1649.         0x1D79C => array(0x3BD),
  1650.         0x1D79D => array(0x3BE),
  1651.         0x1D79E => array(0x3BF),
  1652.         0x1D79F => array(0x3C0),
  1653.         0x1D7A0 => array(0x3C1),
  1654.         0x1D7A1 => array(0x3B8),
  1655.         0x1D7A2 => array(0x3C3),
  1656.         0x1D7A3 => array(0x3C4),
  1657.         0x1D7A4 => array(0x3C5),
  1658.         0x1D7A5 => array(0x3C6),
  1659.         0x1D7A6 => array(0x3C7),
  1660.         0x1D7A7 => array(0x3C8),
  1661.         0x1D7A8 => array(0x3C9),
  1662.         0x1D7BB => array(0x3C3),
  1663.         0x3F9   => array(0x3C3),
  1664.         0x1D2C  => array(0x61),
  1665.         0x1D2D  => array(0xE6),
  1666.         0x1D2E  => array(0x62),
  1667.         0x1D30  => array(0x64),
  1668.         0x1D31  => array(0x65),
  1669.         0x1D32  => array(0x1DD),
  1670.         0x1D33  => array(0x67),
  1671.         0x1D34  => array(0x68),
  1672.         0x1D35  => array(0x69),
  1673.         0x1D36  => array(0x6A),
  1674.         0x1D37  => array(0x6B),
  1675.         0x1D38  => array(0x6C),
  1676.         0x1D39  => array(0x6D),
  1677.         0x1D3A  => array(0x6E),
  1678.         0x1D3C  => array(0x6F),
  1679.         0x1D3D  => array(0x223),
  1680.         0x1D3E  => array(0x70),
  1681.         0x1D3F  => array(0x72),
  1682.         0x1D40  => array(0x74),
  1683.         0x1D41  => array(0x75),
  1684.         0x1D42  => array(0x77),
  1685.         0x213B  => array(0x660x610x78),
  1686.         0x3250  => array(0x700x740x65),
  1687.         0x32CC  => array(0x680x67),
  1688.         0x32CE  => array(0x650x76),
  1689.         0x32CF  => array(0x6C0x740x64),
  1690.         0x337A  => array(0x690x75),
  1691.         0x33DE  => array(0x760x22150x6D),
  1692.         0x33DF  => array(0x610x22150x6D)
  1693.     );
  1694.  
  1695.     /**
  1696.      * Normalization Combining Classes; Code Points not listed
  1697.      * got Combining Class 0.
  1698.      *
  1699.      * @static
  1700.      * @var array 
  1701.      * @access private
  1702.      */
  1703.     private static $_np_norm_combcls = array(
  1704.         0x334   => 1,
  1705.         0x335   => 1,
  1706.         0x336   => 1,
  1707.         0x337   => 1,
  1708.         0x338   => 1,
  1709.         0x93C   => 7,
  1710.         0x9BC   => 7,
  1711.         0xA3C   => 7,
  1712.         0xABC   => 7,
  1713.         0xB3C   => 7,
  1714.         0xCBC   => 7,
  1715.         0x1037  => 7,
  1716.         0x3099  => 8,
  1717.         0x309A  => 8,
  1718.         0x94D   => 9,
  1719.         0x9CD   => 9,
  1720.         0xA4D   => 9,
  1721.         0xACD   => 9,
  1722.         0xB4D   => 9,
  1723.         0xBCD   => 9,
  1724.         0xC4D   => 9,
  1725.         0xCCD   => 9,
  1726.         0xD4D   => 9,
  1727.         0xDCA   => 9,
  1728.         0xE3A   => 9,
  1729.         0xF84   => 9,
  1730.         0x1039  => 9,
  1731.         0x1714  => 9,
  1732.         0x1734  => 9,
  1733.         0x17D2  => 9,
  1734.         0x5B0   => 10,
  1735.         0x5B1   => 11,
  1736.         0x5B2   => 12,
  1737.         0x5B3   => 13,
  1738.         0x5B4   => 14,
  1739.         0x5B5   => 15,
  1740.         0x5B6   => 16,
  1741.         0x5B7   => 17,
  1742.         0x5B8   => 18,
  1743.         0x5B9   => 19,
  1744.         0x5BB   => 20,
  1745.         0x5Bc   => 21,
  1746.         0x5BD   => 22,
  1747.         0x5BF   => 23,
  1748.         0x5C1   => 24,
  1749.         0x5C2   => 25,
  1750.         0xFB1E  => 26,
  1751.         0x64B   => 27,
  1752.         0x64C   => 28,
  1753.         0x64D   => 29,
  1754.         0x64E   => 30,
  1755.         0x64F   => 31,
  1756.         0x650   => 32,
  1757.         0x651   => 33,
  1758.         0x652   => 34,
  1759.         0x670   => 35,
  1760.         0x711   => 36,
  1761.         0xC55   => 84,
  1762.         0xC56   => 91,
  1763.         0xE38   => 103,
  1764.         0xE39   => 103,
  1765.         0xE48   => 107,
  1766.         0xE49   => 107,
  1767.         0xE4A   => 107,
  1768.         0xE4B   => 107,
  1769.         0xEB8   => 118,
  1770.         0xEB9   => 118,
  1771.         0xEC8   => 122,
  1772.         0xEC9   => 122,
  1773.         0xECA   => 122,
  1774.         0xECB   => 122,
  1775.         0xF71   => 129,
  1776.         0xF72   => 130,
  1777.         0xF7A   => 130,
  1778.         0xF7B   => 130,
  1779.         0xF7C   => 130,
  1780.         0xF7D   => 130,
  1781.         0xF80   => 130,
  1782.         0xF74   => 132,
  1783.         0x321   => 202,
  1784.         0x322   => 202,
  1785.         0x327   => 202,
  1786.         0x328   => 202,
  1787.         0x31B   => 216,
  1788.         0xF39   => 216,
  1789.         0x1D165 => 216,
  1790.         0x1D166 => 216,
  1791.         0x1D16E => 216,
  1792.         0x1D16F => 216,
  1793.         0x1D170 => 216,
  1794.         0x1D171 => 216,
  1795.         0x1D172 => 216,
  1796.         0x302A  => 218,
  1797.         0x316   => 220,
  1798.         0x317   => 220,
  1799.         0x318   => 220,
  1800.         0x319   => 220,
  1801.         0x31C   => 220,
  1802.         0x31D   => 220,
  1803.         0x31E   => 220,
  1804.         0x31F   => 220,
  1805.         0x320   => 220,
  1806.         0x323   => 220,
  1807.         0x324   => 220,
  1808.         0x325   => 220,
  1809.         0x326   => 220,
  1810.         0x329   => 220,
  1811.         0x32A   => 220,
  1812.         0x32B   => 220,
  1813.         0x32C   => 220,
  1814.         0x32D   => 220,
  1815.         0x32E   => 220,
  1816.         0x32F   => 220,
  1817.         0x330   => 220,
  1818.         0x331   => 220,
  1819.         0x332   => 220,
  1820.         0x333   => 220,
  1821.         0x339   => 220,
  1822.         0x33A   => 220,
  1823.         0x33B   => 220,
  1824.         0x33C   => 220,
  1825.         0x347   => 220,
  1826.         0x348   => 220,
  1827.         0x349   => 220,
  1828.         0x34D   => 220,
  1829.         0x34E   => 220,
  1830.         0x353   => 220,
  1831.         0x354   => 220,
  1832.         0x355   => 220,
  1833.         0x356   => 220,
  1834.         0x591   => 220,
  1835.         0x596   => 220,
  1836.         0x59B   => 220,
  1837.         0x5A3   => 220,
  1838.         0x5A4   => 220,
  1839.         0x5A5   => 220,
  1840.         0x5A6   => 220,
  1841.         0x5A7   => 220,
  1842.         0x5AA   => 220,
  1843.         0x655   => 220,
  1844.         0x656   => 220,
  1845.         0x6E3   => 220,
  1846.         0x6EA   => 220,
  1847.         0x6ED   => 220,
  1848.         0x731   => 220,
  1849.         0x734   => 220,
  1850.         0x737   => 220,
  1851.         0x738   => 220,
  1852.         0x739   => 220,
  1853.         0x73B   => 220,
  1854.         0x73C   => 220,
  1855.         0x73E   => 220,
  1856.         0x742   => 220,
  1857.         0x744   => 220,
  1858.         0x746   => 220,
  1859.         0x748   => 220,
  1860.         0x952   => 220,
  1861.         0xF18   => 220,
  1862.         0xF19   => 220,
  1863.         0xF35   => 220,
  1864.         0xF37   => 220,
  1865.         0xFC6   => 220,
  1866.         0x193B  => 220,
  1867.         0x20E8  => 220,
  1868.         0x1D17B => 220,
  1869.         0x1D17C => 220,
  1870.         0x1D17D => 220,
  1871.         0x1D17E => 220,
  1872.         0x1D17F => 220,
  1873.         0x1D180 => 220,
  1874.         0x1D181 => 220,
  1875.         0x1D182 => 220,
  1876.         0x1D18A => 220,
  1877.         0x1D18B => 220,
  1878.         0x59A   => 222,
  1879.         0x5AD   => 222,
  1880.         0x1929  => 222,
  1881.         0x302D  => 222,
  1882.         0x302E  => 224,
  1883.         0x302F  => 224,
  1884.         0x1D16D => 226,
  1885.         0x5AE   => 228,
  1886.         0x18A9  => 228,
  1887.         0x302B  => 228,
  1888.         0x300   => 230,
  1889.         0x301   => 230,
  1890.         0x302   => 230,
  1891.         0x303   => 230,
  1892.         0x304   => 230,
  1893.         0x305   => 230,
  1894.         0x306   => 230,
  1895.         0x307   => 230,
  1896.         0x308   => 230,
  1897.         0x309   => 230,
  1898.         0x30A   => 230,
  1899.         0x30B   => 230,
  1900.         0x30C   => 230,
  1901.         0x30D   => 230,
  1902.         0x30E   => 230,
  1903.         0x30F   => 230,
  1904.         0x310   => 230,
  1905.         0x311   => 230,
  1906.         0x312   => 230,
  1907.         0x313   => 230,
  1908.         0x314   => 230,
  1909.         0x33D   => 230,
  1910.         0x33E   => 230,
  1911.         0x33F   => 230,
  1912.         0x340   => 230,
  1913.         0x341   => 230,
  1914.         0x342   => 230,
  1915.         0x343   => 230,
  1916.         0x344   => 230,
  1917.         0x346   => 230,
  1918.         0x34A   => 230,
  1919.         0x34B   => 230,
  1920.         0x34C   => 230,
  1921.         0x350   => 230,
  1922.         0x351   => 230,
  1923.         0x352   => 230,
  1924.         0x357   => 230,
  1925.         0x363   => 230,
  1926.         0x364   => 230,
  1927.         0x365   => 230,
  1928.         0x366   => 230,
  1929.         0x367   => 230,
  1930.         0x368   => 230,
  1931.         0x369   => 230,
  1932.         0x36A   => 230,
  1933.         0x36B   => 230,
  1934.         0x36C   => 230,
  1935.         0x36D   => 230,
  1936.         0x36E   => 230,
  1937.         0x36F   => 230,
  1938.         0x483   => 230,
  1939.         0x484   => 230,
  1940.         0x485   => 230,
  1941.         0x486   => 230,
  1942.         0x592   => 230,
  1943.         0x593   => 230,
  1944.         0x594   => 230,
  1945.         0x595   => 230,
  1946.         0x597   => 230,
  1947.         0x598   => 230,
  1948.         0x599   => 230,
  1949.         0x59C   => 230,
  1950.         0x59D   => 230,
  1951.         0x59E   => 230,
  1952.         0x59F   => 230,
  1953.         0x5A0   => 230,
  1954.         0x5A1   => 230,
  1955.         0x5A8   => 230,
  1956.         0x5A9   => 230,
  1957.         0x5AB   => 230,
  1958.         0x5AC   => 230,
  1959.         0x5AF   => 230,
  1960.         0x5C4   => 230,
  1961.         0x610   => 230,
  1962.         0x611   => 230,
  1963.         0x612   => 230,
  1964.         0x613   => 230,
  1965.         0x614   => 230,
  1966.         0x615   => 230,
  1967.         0x653   => 230,
  1968.         0x654   => 230,
  1969.         0x657   => 230,
  1970.         0x658   => 230,
  1971.         0x6D6   => 230,
  1972.         0x6D7   => 230,
  1973.         0x6D8   => 230,
  1974.         0x6D9   => 230,
  1975.         0x6DA   => 230,
  1976.         0x6DB   => 230,
  1977.         0x6DC   => 230,
  1978.         0x6DF   => 230,
  1979.         0x6E0   => 230,
  1980.         0x6E1   => 230,
  1981.         0x6E2   => 230,
  1982.         0x6E4   => 230,
  1983.         0x6E7   => 230,
  1984.         0x6E8   => 230,
  1985.         0x6EB   => 230,
  1986.         0x6EC   => 230,
  1987.         0x730   => 230,
  1988.         0x732   => 230,
  1989.         0x733   => 230,
  1990.         0x735   => 230,
  1991.         0x736   => 230,
  1992.         0x73A   => 230,
  1993.         0x73D   => 230,
  1994.         0x73F   => 230,
  1995.         0x740   => 230,
  1996.         0x741   => 230,
  1997.         0x743   => 230,
  1998.         0x745   => 230,
  1999.         0x747   => 230,
  2000.         0x749   => 230,
  2001.         0x74A   => 230,
  2002.         0x951   => 230,
  2003.         0x953   => 230,
  2004.         0x954   => 230,
  2005.         0xF82   => 230,
  2006.         0xF83   => 230,
  2007.         0xF86   => 230,
  2008.         0xF87   => 230,
  2009.         0x170D  => 230,
  2010.         0x193A  => 230,
  2011.         0x20D0  => 230,
  2012.         0x20D1  => 230,
  2013.         0x20D4  => 230,
  2014.         0x20D5  => 230,
  2015.         0x20D6  => 230,
  2016.         0x20D7  => 230,
  2017.         0x20DB  => 230,
  2018.         0x20DC  => 230,
  2019.         0x20E1  => 230,
  2020.         0x20E7  => 230,
  2021.         0x20E9  => 230,
  2022.         0xFE20  => 230,
  2023.         0xFE21  => 230,
  2024.         0xFE22  => 230,
  2025.         0xFE23  => 230,
  2026.         0x1D185 => 230,
  2027.         0x1D186 => 230,
  2028.         0x1D187 => 230,
  2029.         0x1D189 => 230,
  2030.         0x1D188 => 230,
  2031.         0x1D1AA => 230,
  2032.         0x1D1AB => 230,
  2033.         0x1D1AC => 230,
  2034.         0x1D1AD => 230,
  2035.         0x315   => 232,
  2036.         0x31A   => 232,
  2037.         0x302C  => 232,
  2038.         0x35F   => 233,
  2039.         0x362   => 233,
  2040.         0x35D   => 234,
  2041.         0x35E   => 234,
  2042.         0x360   => 234,
  2043.         0x361   => 234,
  2044.         0x345   => 240
  2045.     );
  2046.     // }}}
  2047.  
  2048.     // {{{ properties
  2049.     /**
  2050.      * @var string 
  2051.      * @access private
  2052.      */
  2053.     private $_punycode_prefix 'xn--';
  2054.  
  2055.     /**
  2056.      * @access private
  2057.      */
  2058.     private $_invalid_ucs = 0x80000000;
  2059.  
  2060.     /**
  2061.      * @access private
  2062.      */
  2063.     private $_max_ucs = 0x10FFFF;
  2064.  
  2065.     /**
  2066.      * @var int 
  2067.      * @access private
  2068.      */
  2069.     private $_base = 36;
  2070.  
  2071.     /**
  2072.      * @var int 
  2073.      * @access private
  2074.      */
  2075.     private $_tmin = 1;
  2076.  
  2077.     /**
  2078.      * @var int 
  2079.      * @access private
  2080.      */
  2081.     private $_tmax = 26;
  2082.  
  2083.     /**
  2084.      * @var int 
  2085.      * @access private
  2086.      */
  2087.     private $_skew = 38;
  2088.  
  2089.     /**
  2090.      * @var int 
  2091.      * @access private
  2092.      */
  2093.     private $_damp = 700;
  2094.  
  2095.     /**
  2096.      * @var int 
  2097.      * @access private
  2098.      */
  2099.     private $_initial_bias = 72;
  2100.  
  2101.     /**
  2102.      * @var int 
  2103.      * @access private
  2104.      */
  2105.     private $_initial_n = 0x80;
  2106.  
  2107.     /**
  2108.      * @var int 
  2109.      * @access private
  2110.      */
  2111.     private $_slast;
  2112.  
  2113.     /**
  2114.      * @access private
  2115.      */
  2116.     private $_sbase = 0xAC00;
  2117.  
  2118.     /**
  2119.      * @access private
  2120.      */
  2121.     private $_lbase = 0x1100;
  2122.  
  2123.     /**
  2124.      * @access private
  2125.      */
  2126.     private $_vbase = 0x1161;
  2127.  
  2128.     /**
  2129.      * @access private
  2130.      */
  2131.     private $_tbase = 0x11a7;
  2132.  
  2133.     /**
  2134.      * @var int 
  2135.      * @access private
  2136.      */
  2137.     private $_lcount = 19;
  2138.  
  2139.     /**
  2140.      * @var int 
  2141.      * @access private
  2142.      */
  2143.     private $_vcount = 21;
  2144.  
  2145.     /**
  2146.      * @var int 
  2147.      * @access private
  2148.      */
  2149.     private $_tcount = 28;
  2150.  
  2151.     /**
  2152.      * vcount * tcount
  2153.      *
  2154.      * @var int 
  2155.      * @access private
  2156.      */
  2157.     private $_ncount = 588;
  2158.  
  2159.     /**
  2160.      * lcount * tcount * vcount
  2161.      *
  2162.      * @var int 
  2163.      * @access private
  2164.      */
  2165.     private $_scount = 11172;
  2166.  
  2167.     /**
  2168.      * Default encoding for encode()'s input and decode()'s output is UTF-8;
  2169.      * Other possible encodings are ucs4_string and ucs4_array
  2170.      * See {@link setParams()} for how to select these
  2171.      *
  2172.      * @var bool 
  2173.      * @access private
  2174.      */
  2175.     private $_api_encoding 'utf8';
  2176.  
  2177.     /**
  2178.      * Overlong UTF-8 encodings are forbidden
  2179.      *
  2180.      * @var bool 
  2181.      * @access private
  2182.      */
  2183.     private $_allow_overlong = false;
  2184.  
  2185.     /**
  2186.      * Behave strict or not
  2187.      *
  2188.      * @var bool 
  2189.      * @access private
  2190.      */
  2191.     private $_strict_mode = false;
  2192.  
  2193.     /**
  2194.     * In case of error (not caught by Exception handling), the error message can be found here
  2195.     *
  2196.     * @var string 
  2197.     * @access public
  2198.     */
  2199.     public $_error = false;
  2200.     // }}}
  2201.  
  2202.  
  2203.     // {{{ constructor
  2204.     /**
  2205.      * Constructor
  2206.      *
  2207.      * @param  array  $options 
  2208.      * @access public
  2209.      * @see    setParams()
  2210.      */
  2211.     public function __construct($options = null)
  2212.     {
  2213.         $this->_slast $this->_sbase $this->_lcount $this->_vcount $this->_tcount;
  2214.  
  2215.         if (is_array($options)) {
  2216.             $this->setParams($options);
  2217.         }
  2218.     }
  2219.     // }}}
  2220.  
  2221.  
  2222.     /**
  2223.     * Sets a new option value. Available options and values:
  2224.     * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8,
  2225.     *         'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8]
  2226.     * [overlong - Unicode does not allow unnecessarily long encodings of chars,
  2227.     *             to allow this, set this parameter to true, else to false;
  2228.     *             default is false.]
  2229.     * [strict - true: strict mode, good for registration purposes - Causes errors
  2230.     *           on failures; false: loose mode, ideal for "wildlife" applications
  2231.     *           by silently ignoring errors and returning the original input instead
  2232.     *
  2233.     * @param    mixed     Parameter to set (string: single parameter; array of Parameter => Value pairs)
  2234.     * @param    string    Value to use (if parameter 1 is a string)
  2235.     * @return   boolean   true on success, false otherwise
  2236.     * @access   public
  2237.     */
  2238.     public function setParams($option$value = false)
  2239.     {
  2240.         if (!is_array($option)) {
  2241.             $option = array($option => $value);
  2242.         }
  2243.  
  2244.         foreach ($option as $k => $v{
  2245.             switch ($k{
  2246.             case 'encoding':
  2247.                 switch ($v{
  2248.                 case 'utf8':
  2249.                 case 'ucs4_string':
  2250.                 case 'ucs4_array':
  2251.                     $this->_api_encoding $v;
  2252.                     break;
  2253.  
  2254.                 default:
  2255.                     throw new Exception('Set Parameter: Unknown parameter '.$v.' for option '.$k);
  2256.                 }
  2257.  
  2258.                 break;
  2259.  
  2260.             case 'overlong':
  2261.                 $this->_allow_overlong ($v? true : false;
  2262.                 break;
  2263.  
  2264.             case 'strict':
  2265.                 $this->_strict_mode ($v? true : false;
  2266.                 break;
  2267.  
  2268.             default:
  2269.                 return false;
  2270.             }
  2271.         }
  2272.  
  2273.         return true;
  2274.     }
  2275.  
  2276.     /**
  2277.      * Encode a given UTF-8 domain name.
  2278.      *
  2279.      * @param    string     $decoded     Domain name (UTF-8 or UCS-4)
  2280.      *  [@param    string     $encoding    Desired input encoding, see {@link set_parameter}]
  2281.      * @return   string                  Encoded Domain name (ACE string)
  2282.      * @return   mixed                   processed string
  2283.      * @throws   Exception
  2284.      * @access   public
  2285.      */
  2286.     public function encode($decoded$one_time_encoding = false)
  2287.     {
  2288.         // Forcing conversion of input to UCS4 array
  2289.         // If one time encoding is given, use this, else the objects property
  2290.         switch (($one_time_encoding$one_time_encoding $this->_api_encoding{
  2291.         case 'utf8':
  2292.             $decoded $this->_utf8_to_ucs4($decoded);
  2293.             break;
  2294.         case 'ucs4_string':
  2295.            $decoded $this->_ucs4_string_to_ucs4($decoded);
  2296.         case 'ucs4_array'// No break; before this line. Catch case, but do nothing
  2297.            break;
  2298.         default:
  2299.             throw new Exception('Unsupported input format');
  2300.         }
  2301.  
  2302.         // No input, no output, what else did you expect?
  2303.         if (empty($decoded)) return '';
  2304.  
  2305.         // Anchors for iteration
  2306.         $last_begin = 0;
  2307.         // Output string
  2308.         $output '';
  2309.  
  2310.         foreach ($decoded as $k => $v{
  2311.             // Make sure to use just the plain dot
  2312.             switch($v{
  2313.             case 0x3002:
  2314.             case 0xFF0E:
  2315.             case 0xFF61:
  2316.                 $decoded[$k= 0x2E;
  2317.                 // It's right, no break here
  2318.                 // The codepoints above have to be converted to dots anyway
  2319.  
  2320.             // Stumbling across an anchoring character
  2321.             case 0x2E:
  2322.             case 0x2F:
  2323.             case 0x3A:
  2324.             case 0x3F:
  2325.             case 0x40:
  2326.                 // Neither email addresses nor URLs allowed in strict mode
  2327.                 if ($this->_strict_mode{
  2328.                    throw new Exception('Neither email addresses nor URLs are allowed in strict mode.');
  2329.                 else {
  2330.                     // Skip first char
  2331.                     if ($k{
  2332.                         $encoded '';
  2333.                         $encoded $this->_encode(array_slice($decoded$last_begin(($k)-$last_begin)));
  2334.                         if ($encoded{
  2335.                             $output .= $encoded;
  2336.                         else {
  2337.                             $output .= $this->_ucs4_to_utf8(array_slice($decoded$last_begin(($k)-$last_begin)));
  2338.                         }
  2339.                         $output .= chr($decoded[$k]);
  2340.                     }
  2341.                     $last_begin $k + 1;
  2342.                 }
  2343.             }
  2344.         }
  2345.         // Catch the rest of the string
  2346.         if ($last_begin{
  2347.             $inp_len sizeof($decoded);
  2348.             $encoded '';
  2349.             $encoded $this->_encode(array_slice($decoded$last_begin(($inp_len)-$last_begin)));
  2350.             if ($encoded{
  2351.                 $output .= $encoded;
  2352.             else {
  2353.                 $output .= $this->_ucs4_to_utf8(array_slice($decoded$last_begin(($inp_len)-$last_begin)));
  2354.             }
  2355.             return $output;
  2356.         else {
  2357.             if ($output $this->_encode($decoded)) {
  2358.                 return $output;
  2359.             else {
  2360.                 return $this->_ucs4_to_utf8($decoded);
  2361.             }
  2362.         }
  2363.     }
  2364.  
  2365.     /**
  2366.      * Decode a given ACE domain name.
  2367.      *
  2368.      * @param    string     $encoded     Domain name (ACE string)
  2369.      *  [@param    string     $encoding    Desired output encoding, see {@link set_parameter}]
  2370.      * @return   string                  Decoded Domain name (UTF-8 or UCS-4)
  2371.      * @throws   Exception
  2372.      * @access   public
  2373.      */
  2374.     public function decode($input$one_time_encoding = false)
  2375.     {
  2376.         // Optionally set
  2377.         if ($one_time_encoding{
  2378.             switch ($one_time_encoding{
  2379.             case 'utf8':
  2380.             case 'ucs4_string':
  2381.             case 'ucs4_array':
  2382.                 break;
  2383.             default:
  2384.                 $this->_error('Unknown encoding '.$one_time_encoding);
  2385.                 return false;
  2386.             }
  2387.         }
  2388.         // Make sure to drop any newline characters around
  2389.         $input trim($input);
  2390.  
  2391.         // Negotiate input and try to determine, wether it is a plain string,
  2392.         // an email address or something like a complete URL
  2393.         if (strpos($input'@')) // Maybe it is an email address
  2394.             // No no in strict mode
  2395.             if ($this->_strict_mode{
  2396.                 throw new Exception('Only simple domain name parts can be handled in strict mode');
  2397.             }
  2398.             list($email_pref$inputexplode('@'$input2);
  2399.             $arr explode('.'$input);
  2400.             foreach ($arr as $k => $v{
  2401.                 $conv $this->_decode($v);
  2402.                 if ($conv$arr[$k$conv;
  2403.             }
  2404.             $return $email_pref '@' join('.'$arr);
  2405.         elseif (preg_match('![:\./]!'$input)) // Or a complete domain name (with or without paths / parameters)
  2406.             // No no in strict mode
  2407.             if ($this->_strict_mode{
  2408.                 throw new Exception('Only simple domain name parts can be handled in strict mode');
  2409.             }
  2410.             $parsed parse_url($input);
  2411.             if (isset($parsed['host'])) {
  2412.                 $arr explode('.'$parsed['host']);
  2413.                 foreach ($arr as $k => $v{
  2414.                     $conv $this->_decode($v);
  2415.                     if ($conv$arr[$k$conv;
  2416.                 }
  2417.                 $parsed['host'join('.'$arr);
  2418.                 if (isset($parsed['scheme'])) {
  2419.                     $parsed['scheme'.= (strtolower($parsed['scheme']== 'mailto'':' '://';
  2420.                 }
  2421.                 $return join(''$parsed);
  2422.             else // parse_url seems to have failed, try without it
  2423.                 $arr explode('.'$input);
  2424.                 foreach ($arr as $k => $v{
  2425.                     $conv $this->_decode($v);
  2426.                     if ($conv$arr[$k$conv;
  2427.                 }
  2428.                 $return join('.'$arr);
  2429.             }
  2430.         else // Otherwise we consider it being a pure domain name string
  2431.             $return $this->_decode($input);
  2432.         }
  2433.         // The output is UTF-8 by default, other output formats need conversion here
  2434.         // If one time encoding is given, use this, else the objects property
  2435.         switch (($one_time_encoding$one_time_encoding $this->_api_encoding{
  2436.         case 'utf8':
  2437.             return $return;
  2438.             break;
  2439.         case 'ucs4_string':
  2440.            return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
  2441.            break;
  2442.         case 'ucs4_array':
  2443.             return $this->_utf8_to_ucs4($return);
  2444.             break;
  2445.         default:
  2446.             throw new Exception('Unsupported output format');
  2447.         }
  2448.     }
  2449.  
  2450.  
  2451.     // {{{ private
  2452.     /**
  2453.      * The actual encoding algorithm.
  2454.      *
  2455.      * @return   string 
  2456.      * @throws   Exception
  2457.      * @access   private
  2458.      */
  2459.     private function _encode($decoded)
  2460.     {
  2461.         // We cannot encode a domain name containing the Punycode prefix
  2462.         $extract strlen($this->_punycode_prefix);
  2463.         $check_pref $this->_utf8_to_ucs4($this->_punycode_prefix);
  2464.         $check_deco array_slice($decoded0$extract);
  2465.  
  2466.         if ($check_pref == $check_deco{
  2467.             throw new Exception('This is already a punycode string');
  2468.         }
  2469.         // We will not try to encode strings consisting of basic code points only
  2470.         $encodable = false;
  2471.         foreach ($decoded as $k => $v{
  2472.             if ($v > 0x7a{
  2473.                 $encodable = true;
  2474.                 break;
  2475.             }
  2476.         }
  2477.         if (!$encodable{
  2478.             if ($this->_strict_mode{
  2479.                 throw new Exception('The given string does not contain encodable chars');
  2480.             else {
  2481.                 return false;
  2482.             }
  2483.         }
  2484.  
  2485.         // Do NAMEPREP
  2486.         try {
  2487.             $decoded $this->_nameprep($decoded);
  2488.         catch (Exception $e{
  2489.             // hmm, serious - rethrow
  2490.             throw $e;
  2491.         }
  2492.  
  2493.         $deco_len count($decoded);
  2494.  
  2495.         // Empty array
  2496.         if (!$deco_len{
  2497.             return false;
  2498.         }
  2499.  
  2500.         // How many chars have been consumed
  2501.         $codecount = 0;
  2502.  
  2503.         // Start with the prefix; copy it to output
  2504.         $encoded $this->_punycode_prefix;
  2505.  
  2506.         $encoded '';
  2507.         // Copy all basic code points to output
  2508.         for ($i = 0; $i $deco_len; ++$i{
  2509.             if (preg_match('![0-9a-zA-Z-]!'chr($decoded[$i]))) {
  2510.                 $encoded .= chr($decoded[$i]);
  2511.                 $codecount++;
  2512.             }
  2513.         }
  2514.  
  2515.         // All codepoints were basic ones
  2516.         if ($codecount == $deco_len{
  2517.             return $encoded;
  2518.         }
  2519.         // Start with the prefix; copy it to output
  2520.         $encoded $this->_punycode_prefix $encoded;
  2521.  
  2522.         // If we have basic code points in output, add an hyphen to the end
  2523.         if ($codecount{
  2524.             $encoded .= '-';
  2525.         }
  2526.  
  2527.         // Now find and encode all non-basic code points
  2528.         $is_first  = true;
  2529.         $cur_code  $this->_initial_n;
  2530.         $bias      $this->_initial_bias;
  2531.         $delta     = 0;
  2532.  
  2533.         while ($codecount $deco_len{
  2534.             // Find the smallest code point >= the current code point and
  2535.             // remember the last ouccrence of it in the input
  2536.             for ($i = 0$next_code $this->_max_ucs$i $deco_len$i++{
  2537.                 if ($decoded[$i>= $cur_code && $decoded[$i<= $next_code{
  2538.                     $next_code $decoded[$i];
  2539.                 }
  2540.             }
  2541.  
  2542.             $delta += ($next_code $cur_code($codecount + 1);
  2543.             $cur_code $next_code;
  2544.  
  2545.             // Scan input again and encode all characters whose code point is $cur_code
  2546.             for ($i = 0; $i $deco_len$i++{
  2547.                 if ($decoded[$i$cur_code{
  2548.                     $delta++;
  2549.                 else if ($decoded[$i== $cur_code{
  2550.                     for ($q $delta$k $this->_base; 1; $k += $this->_base{
  2551.                         $t ($k <= $bias)?
  2552.                             $this->_tmin :
  2553.                             (($k >= $bias $this->_tmax)$this->_tmax $k $bias);
  2554.  
  2555.                         if ($q $t{
  2556.                             break;
  2557.                         }
  2558.  
  2559.                         $encoded .= $this->_encodeDigit(ceil($t (($q $t($this->_base $t))));
  2560.                         $q ($q $t($this->_base $t);
  2561.                     }
  2562.  
  2563.                     $encoded .= $this->_encodeDigit($q);
  2564.                     $bias $this->_adapt($delta$codecount + 1$is_first);
  2565.                     $codecount++;
  2566.                     $delta = 0;
  2567.                     $is_first = false;
  2568.                 }
  2569.             }
  2570.  
  2571.             $delta++;
  2572.             $cur_code++;
  2573.         }
  2574.  
  2575.         return $encoded;
  2576.     }
  2577.  
  2578.     /**
  2579.      * The actual decoding algorithm.
  2580.      *
  2581.      * @return   string 
  2582.      * @throws   Exception
  2583.      * @access   private
  2584.      */
  2585.     private function _decode($encoded)
  2586.     {
  2587.         // We do need to find the Punycode prefix
  2588.         if (!preg_match('!^' preg_quote($this->_punycode_prefix'!''!'$encoded)) {
  2589.             return false;
  2590.         }
  2591.  
  2592.         $encode_test preg_replace('!^' preg_quote($this->_punycode_prefix'!''!'''$encoded);
  2593.  
  2594.         // If nothing left after removing the prefix, it is hopeless
  2595.         if (!$encode_test{
  2596.             return false;
  2597.         }
  2598.  
  2599.         // Find last occurence of the delimiter
  2600.         $delim_pos strrpos($encoded'-');
  2601.  
  2602.         if ($delim_pos strlen($this->_punycode_prefix)) {
  2603.             for ($k strlen($this->_punycode_prefix)$k $delim_pos; ++$k{
  2604.                 $decoded[ord($encoded{$k});
  2605.             }
  2606.         else {
  2607.             $decoded = array();
  2608.         }
  2609.  
  2610.         $deco_len count($decoded);
  2611.         $enco_len strlen($encoded);
  2612.  
  2613.         // Wandering through the strings; init
  2614.         $is_first = true;
  2615.         $bias     $this->_initial_bias;
  2616.         $idx      = 0;
  2617.         $char     $this->_initial_n;
  2618.  
  2619.         for ($enco_idx ($delim_pos)($delim_pos + 1: 0; $enco_idx $enco_len; ++$deco_len{
  2620.             for ($old_idx $idx$w = 1$k $this->_base; 1 ; $k += $this->_base{
  2621.                 $digit $this->_decodeDigit($encoded{$enco_idx++});
  2622.                 $idx += $digit $w;
  2623.  
  2624.                 $t ($k <= $bias?
  2625.                     $this->_tmin :
  2626.                     (($k >= $bias $this->_tmax)$this->_tmax ($k $bias));
  2627.  
  2628.                 if ($digit $t{
  2629.                     break;
  2630.                 }
  2631.  
  2632.                 $w = (int)($w ($this->_base $t));
  2633.             }
  2634.  
  2635.             $bias      $this->_adapt($idx $old_idx$deco_len + 1$is_first);
  2636.             $is_first  = false;
  2637.             $char     += (int) ($idx ($deco_len + 1));
  2638.             $idx      %= ($deco_len + 1);
  2639.  
  2640.             if ($deco_len > 0{
  2641.                 // Make room for the decoded char
  2642.                 for ($i $deco_len$i $idx$i--{
  2643.                     $decoded[$i$decoded[($i - 1)];
  2644.                 }
  2645.             }
  2646.  
  2647.             $decoded[$idx++$char;
  2648.         }
  2649.  
  2650.         try {
  2651.             return $this->_ucs4_to_utf8($decoded);
  2652.         catch (Exception $e{
  2653.             // rethrow
  2654.             throw $e;
  2655.         }
  2656.     }
  2657.  
  2658.     /**
  2659.      * Adapt the bias according to the current code point and position.
  2660.      *
  2661.      * @access   private
  2662.      */
  2663.     private function _adapt($delta$npoints$is_first)
  2664.     {
  2665.         $delta = (int) ($is_first ($delta $this->_damp($delta / 2));
  2666.         $delta += (int) ($delta $npoints);
  2667.  
  2668.         for ($k = 0; $delta (($this->_base $this->_tmin$this->_tmax/ 2; $k += $this->_base{
  2669.             $delta = (int) ($delta ($this->_base $this->_tmin));
  2670.         }
  2671.  
  2672.         return (int) ($k ($this->_base $this->_tmin + 1$delta ($delta $this->_skew));
  2673.     }
  2674.  
  2675.     /**
  2676.      * Encoding a certain digit.
  2677.      *
  2678.      * @access   private
  2679.      */
  2680.     private function _encodeDigit($d)
  2681.     {
  2682.         return chr($d + 22 + 75 * ($d < 26));
  2683.     }
  2684.  
  2685.     /**
  2686.      * Decode a certain digit.
  2687.      *
  2688.      * @access   private
  2689.      */
  2690.     private function _decodeDigit($cp)
  2691.     {
  2692.         $cp ord($cp);
  2693.         return ($cp - 48 < 10)$cp - 22 : (($cp - 65 < 26)$cp - 65 : (($cp - 97 < 26)$cp - 97 : $this->_base));
  2694.     }
  2695.  
  2696.     /**
  2697.      * Do Nameprep according to RFC3491 and RFC3454.
  2698.      *
  2699.      * @param    array      $input       Unicode Characters
  2700.      * @return   string                  Unicode Characters, Nameprep'd
  2701.      * @throws   Exception
  2702.      * @access   private
  2703.      */
  2704.     private function _nameprep($input)
  2705.     {
  2706.         $output = array();
  2707.  
  2708.         // Walking through the input array, performing the required steps on each of
  2709.         // the input chars and putting the result into the output array
  2710.         // While mapping required chars we apply the cannonical ordering
  2711.  
  2712.         foreach ($input as $v{
  2713.             // Map to nothing == skip that code point
  2714.             if (in_array($vself::$_np_map_nothing)) {
  2715.                 continue;
  2716.             }
  2717.  
  2718.             // Try to find prohibited input
  2719.             if (in_array($vself::$_np_prohibit|| in_array($vself::$_general_prohibited)) {
  2720.                 throw new Exception('NAMEPREP: Prohibited input U+' sprintf('%08X'$v));
  2721.             }
  2722.  
  2723.             foreach (self::$_np_prohibit_ranges as $range{
  2724.                 if ($range[0<= $v && $v <= $range[1]{
  2725.                     throw new Exception('NAMEPREP: Prohibited input U+' sprintf('%08X'$v));
  2726.                 }
  2727.             }
  2728.  
  2729.             // Hangul syllable decomposition
  2730.             if (0xAC00 <= $v && $v <= 0xD7AF{
  2731.                 foreach ($this->_hangulDecompose($vas $out{
  2732.                     $output[$out;
  2733.                 }
  2734.             else if (isset(self::$_np_replacemaps[$v])) // There's a decomposition mapping for that code point
  2735.                 foreach ($this->_applyCannonicalOrdering(self::$_np_replacemaps[$v]as $out{
  2736.                     $output[$out;
  2737.                 }
  2738.             else {
  2739.                 $output[$v;
  2740.             }
  2741.         }
  2742.  
  2743.         // Combine code points
  2744.  
  2745.         $last_class   = 0;
  2746.         $last_starter = 0;
  2747.         $out_len      = count($output);
  2748.  
  2749.         for ($i = 0; $i $out_len; ++$i{
  2750.             $class $this->_getCombiningClass($output[$i]);
  2751.  
  2752.             if ((!$last_class || $last_class != $class&& $class{
  2753.                 // Try to match
  2754.                 $seq_len $i $last_starter;
  2755.                 $out $this->_combine(array_slice($output$last_starter$seq_len));
  2756.  
  2757.                 // On match: Replace the last starter with the composed character and remove
  2758.                 // the now redundant non-starter(s)
  2759.                 if ($out{
  2760.                     $output[$last_starter$out;
  2761.  
  2762.                     if (count($out!= $seq_len{
  2763.                         for ($j $i + 1; $j $out_len; ++$j{
  2764.                             $output[$j - 1$output[$j];
  2765.                         }
  2766.  
  2767.                         unset($output[$out_len]);
  2768.                     }
  2769.  
  2770.                     // Rewind the for loop by one, since there can be more possible compositions
  2771.                     $i--;
  2772.                     $out_len--;
  2773.                     $last_class ($i == $last_starter)? 0 : $this->_getCombiningClass($output[$i - 1]);
  2774.  
  2775.                     continue;
  2776.                 }
  2777.             }
  2778.  
  2779.             // The current class is 0
  2780.             if (!$class{
  2781.                 $last_starter $i;
  2782.             }
  2783.  
  2784.             $last_class $class;
  2785.         }
  2786.  
  2787.         return $output;
  2788.     }
  2789.  
  2790.     /**
  2791.      * Decomposes a Hangul syllable
  2792.      * (see http://www.unicode.org/unicode/reports/tr15/#Hangul).
  2793.      *
  2794.      * @param    integer    $char        32bit UCS4 code point
  2795.      * @return   array                   Either Hangul Syllable decomposed or original 32bit
  2796.      *                                    value as one value array
  2797.      * @access   private
  2798.      */
  2799.     private function _hangulDecompose($char)
  2800.     {
  2801.         $sindex $char $this->_sbase;
  2802.  
  2803.         if ($sindex < 0 || $sindex >= $this->_scount{
  2804.             return array($char);
  2805.         }
  2806.  
  2807.         $result   = array();
  2808.         $T        $this->_tbase $sindex $this->_tcount;
  2809.         $result[= (int)($this->_lbase +  $sindex $this->_ncount);
  2810.         $result[= (int)($this->_vbase ($sindex $this->_ncount$this->_tcount);
  2811.  
  2812.         if ($T != $this->_tbase{
  2813.             $result[$T;
  2814.         }
  2815.  
  2816.         return $result;
  2817.     }
  2818.  
  2819.     /**
  2820.      * Ccomposes a Hangul syllable
  2821.      * (see http://www.unicode.org/unicode/reports/tr15/#Hangul).
  2822.      *
  2823.      * @param    array      $input       Decomposed UCS4 sequence
  2824.      * @return   array                   UCS4 sequence with syllables composed
  2825.      * @access   private
  2826.      */
  2827.     private function _hangulCompose($input)
  2828.     {
  2829.         $inp_len count($input);
  2830.  
  2831.         if (!$inp_len{
  2832.             return array();
  2833.         }
  2834.  
  2835.         $result   = array();
  2836.         $last     $input[0];
  2837.         $result[$last// copy first char from input to output
  2838.  
  2839.         for ($i = 1; $i $inp_len; ++$i{
  2840.             $char $input[$i];
  2841.  
  2842.             // Find out, wether two current characters from L and V
  2843.             $lindex $last $this->_lbase;
  2844.  
  2845.             if (0 <= $lindex && $lindex $this->_lcount{
  2846.                 $vindex $char $this->_vbase;
  2847.  
  2848.                 if (0 <= $vindex && $vindex $this->_vcount{
  2849.                     // create syllable of form LV
  2850.                     $last    ($this->_sbase ($lindex $this->_vcount $vindex$this->_tcount);
  2851.                     $out_off count($result- 1;
  2852.                     $result[$out_off$last// reset last
  2853.  
  2854.                     // discard char
  2855.                     continue;
  2856.                 }
  2857.             }
  2858.  
  2859.             // Find out, wether two current characters are LV and T
  2860.             $sindex $last $this->_sbase;
  2861.  
  2862.             if (0 <= $sindex && $sindex $this->_scount && ($sindex $this->_tcount== 0{
  2863.                 $tindex $char $this->_tbase;
  2864.  
  2865.                 if (0 <= $tindex && $tindex <= $this->_tcount{
  2866.                     // create syllable of form LVT
  2867.                     $last += $tindex;
  2868.                     $out_off count($result- 1;
  2869.                     $result[$out_off$last// reset last
  2870.  
  2871.                     // discard char
  2872.                     continue;
  2873.                 }
  2874.             }
  2875.  
  2876.             // if neither case was true, just add the character
  2877.             $last $char;
  2878.             $result[$char;
  2879.         }
  2880.  
  2881.         return $result;
  2882.     }
  2883.  
  2884.     /**
  2885.      * Returns the combining class of a certain wide char.
  2886.      *
  2887.      * @param    integer    $char        Wide char to check (32bit integer)
  2888.      * @return   integer                 Combining class if found, else 0
  2889.      * @access   private
  2890.      */
  2891.     private function _getCombiningClass($char)
  2892.     {
  2893.         return isset(self::$_np_norm_combcls[$char])? self::$_np_norm_combcls[$char: 0;
  2894.     }
  2895.  
  2896.     /**
  2897.      * Apllies the cannonical ordering of a decomposed UCS4 sequence.
  2898.      *
  2899.      * @param    array      $input       Decomposed UCS4 sequence
  2900.      * @return   array                   Ordered USC4 sequence
  2901.      * @access   private
  2902.      */
  2903.     private function _applyCannonicalOrdering($input)
  2904.     {
  2905.         $swap = true;
  2906.         $size count($input);
  2907.  
  2908.         while ($swap{
  2909.             $swap = false;
  2910.             $last $this->_getCombiningClass($input[0]);
  2911.  
  2912.             for ($i = 0; $i $size - 1; ++$i{
  2913.                 $next $this->_getCombiningClass($input[$i + 1]);
  2914.  
  2915.                 if ($next != 0 && $last $next{
  2916.                     // Move item leftward until it fits
  2917.                     for ($j $i + 1; $j > 0; --$j{
  2918.                         if ($this->_getCombiningClass($input[$j - 1]<= $next{
  2919.                             break;
  2920.                         }
  2921.  
  2922.                         $t $input[$j];
  2923.                         $input[$j$input[$j - 1];
  2924.                         $input[$j - 1$t;
  2925.                         $swap = 1;
  2926.                     }
  2927.  
  2928.                     // Reentering the loop looking at the old character again
  2929.                     $next $last;
  2930.                 }
  2931.  
  2932.                 $last $next;
  2933.             }
  2934.         }
  2935.  
  2936.         return $input;
  2937.     }
  2938.  
  2939.     /**
  2940.      * Do composition of a sequence of starter and non-starter.
  2941.      *
  2942.      * @param    array      $input       UCS4 Decomposed sequence
  2943.      * @return   array                   Ordered USC4 sequence
  2944.      * @access   private
  2945.      */
  2946.     private function _combine($input)
  2947.     {
  2948.         $inp_len count($input);
  2949.  
  2950.         // Is it a Hangul syllable?
  2951.         if (1 != $inp_len{
  2952.             $hangul $this->_hangulCompose($input);
  2953.  
  2954.             // This place is probably wrong
  2955.             if (count($hangul!= $inp_len{
  2956.                 return $hangul;
  2957.             }
  2958.         }
  2959.  
  2960.         foreach (self::$_np_replacemaps as $np_src => $np_target{
  2961.             if ($np_target[0!= $input[0]{
  2962.                 continue;
  2963.             }
  2964.  
  2965.             if (count($np_target!= $inp_len{
  2966.                 continue;
  2967.             }
  2968.  
  2969.             $hit = false;
  2970.  
  2971.             foreach ($input as $k2 => $v2{
  2972.                 if ($v2 == $np_target[$k2]{
  2973.                     $hit = true;
  2974.                 else {
  2975.                     $hit = false;
  2976.                     break;
  2977.                 }
  2978.             }
  2979.  
  2980.             if ($hit{
  2981.                 return $np_src;
  2982.             }
  2983.         }
  2984.  
  2985.         return false;
  2986.     }
  2987.  
  2988.     /**
  2989.      * This converts an UTF-8 encoded string to its UCS-4 (array) representation
  2990.      * By talking about UCS-4 we mean arrays of 32bit integers representing
  2991.      * each of the "chars". This is due to PHP not being able to handle strings with
  2992.      * bit depth different from 8. This applies to the reverse method _ucs4_to_utf8(), too.
  2993.      * The following UTF-8 encodings are supported:
  2994.      *
  2995.      * bytes bits  representation
  2996.      * 1        7  0xxxxxxx
  2997.      * 2       11  110xxxxx 10xxxxxx
  2998.      * 3       16  1110xxxx 10xxxxxx 10xxxxxx
  2999.      * 4       21  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  3000.      * 5       26  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  3001.      * 6       31  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  3002.      *
  3003.      * Each x represents a bit that can be used to store character data.
  3004.      *
  3005.      * @access   private
  3006.      */
  3007.     private function _utf8_to_ucs4($input)
  3008.     {
  3009.         $output = array();
  3010.         $out_len = 0;
  3011.         $inp_len strlen($input);
  3012.         $mode 'next';
  3013.         $test 'none';
  3014.         for ($k = 0; $k $inp_len; ++$k{
  3015.             $v ord($input{$k})// Extract byte from input string
  3016.  
  3017.             if ($v < 128// We found an ASCII char - put into stirng as is
  3018.                 $output[$out_len$v;
  3019.                 ++$out_len;
  3020.                 if ('add' == $mode{
  3021.                     $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
  3022.                     return false;
  3023.                 }
  3024.                 continue;
  3025.             }
  3026.             if ('next' == $mode// Try to find the next start byte; determine the width of the Unicode char
  3027.                 $start_byte $v;
  3028.                 $mode 'add';
  3029.                 $test 'range';
  3030.                 if ($v >> 5 == 6// &110xxxxx 10xxxxx
  3031.                     $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
  3032.                     $v ($v - 192<< 6;
  3033.                 elseif ($v >> 4 == 14// &1110xxxx 10xxxxxx 10xxxxxx
  3034.                     $next_byte = 1;
  3035.                     $v ($v - 224<< 12;
  3036.                 elseif ($v >> 3 == 30// &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  3037.                     $next_byte = 2;
  3038.                     $v ($v - 240<< 18;
  3039.                 elseif ($v >> 2 == 62// &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  3040.                     $next_byte = 3;
  3041.                     $v ($v - 248<< 24;
  3042.                 elseif ($v >> 1 == 126// &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  3043.                     $next_byte = 4;
  3044.                     $v ($v - 252<< 30;
  3045.                 else {
  3046.                     $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k);
  3047.                     return false;
  3048.                 }
  3049.                 if ('add' == $mode{
  3050.                     $output[$out_len= (int) $v;
  3051.                     ++$out_len;
  3052.                     continue;
  3053.                 }
  3054.             }
  3055.             if ('add' == $mode{
  3056.                 if (!$this->_allow_overlong && $test == 'range'{
  3057.                     $test 'none';
  3058.                     if (($v < 0xA0 && $start_byte == 0xE0|| ($v < 0x90 && $start_byte == 0xF0|| ($v > 0x8F && $start_byte == 0xF4)) {
  3059.                         $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
  3060.                         return false;
  3061.                     }
  3062.                 }
  3063.                 if ($v >> 6 == 2// Bit mask must be 10xxxxxx
  3064.                     $v ($v - 128<< ($next_byte * 6);
  3065.                     $output[($out_len - 1)+= $v;
  3066.                     --$next_byte;
  3067.                 else {
  3068.                     $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
  3069.                     return false;
  3070.                 }
  3071.                 if ($next_byte < 0{
  3072.                     $mode 'next';
  3073.                 }
  3074.             }
  3075.         // for
  3076.         return $output;
  3077.     }
  3078.  
  3079.     /**
  3080.      * Convert UCS-4 array into UTF-8 string.
  3081.      *
  3082.      * @throws   Exception
  3083.      * @access   private
  3084.      */
  3085.     private function _ucs4_to_utf8($input)
  3086.     {
  3087.         $output '';
  3088.  
  3089.         foreach ($input as $v{
  3090.             // $v = ord($v);
  3091.  
  3092.             if ($v < 128{
  3093.                 // 7bit are transferred literally
  3094.                 $output .= chr($v);
  3095.             else if ($v < 1 << 11{
  3096.                 // 2 bytes
  3097.                 $output .= chr(192 + ($v >> 6))
  3098.                     . chr(128 + ($v 63));
  3099.             else if ($v < 1 << 16{
  3100.                 // 3 bytes
  3101.                 $output .= chr(224 + ($v >> 12))
  3102.                     . chr(128 + (($v >> 663))
  3103.                     . chr(128 + ($v 63));
  3104.             else if ($v < 1 << 21{
  3105.                 // 4 bytes
  3106.                 $output .= chr(240 + ($v >> 18))
  3107.                     . chr(128 + (($v >> 1263))
  3108.                     . chr(128 + (($v >>  663))
  3109.                     . chr(128 + ($v 63));
  3110.             else if ($v < 1 << 26{
  3111.                 // 5 bytes
  3112.                 $output .= chr(248 + ($v >> 24))
  3113.                     . chr(128 + (($v >> 1863))
  3114.                     . chr(128 + (($v >> 1263))
  3115.                     . chr(128 + (($v >>  663))
  3116.                     . chr(128 + ($v 63));
  3117.             else if ($v < 1 << 31{
  3118.                 // 6 bytes
  3119.                 $output .= chr(252 + ($v >> 30))
  3120.                     . chr(128 + (($v >> 2463))
  3121.                     . chr(128 + (($v >> 1863))
  3122.                     . chr(128 + (($v >> 1263))
  3123.                     . chr(128 + (($v >>  663))
  3124.                     . chr(128 + ($v 63));
  3125.             else {
  3126.                 throw new Exception('Conversion from UCS-4 to UTF-8 failed: malformed input at byte ' $k);
  3127.             }
  3128.         }
  3129.  
  3130.         return $output;
  3131.     }
  3132.  
  3133.     /**
  3134.      * Convert UCS-4 array into UCS-4 string
  3135.      *
  3136.      * @throws   Exception
  3137.      * @access   private
  3138.      */
  3139.     private function _ucs4_to_ucs4_string($input)
  3140.     {
  3141.         $output '';
  3142.         // Take array values and split output to 4 bytes per value
  3143.         // The bit mask is 255, which reads &11111111
  3144.         foreach ($input as $v{
  3145.             $output .= ($v (255 << 24>> 24($v (255 << 16>> 16($v (255 << 8>> 8($v 255);
  3146.         }
  3147.         return $output;
  3148.     }
  3149.  
  3150.     /**
  3151.      * Convert UCS-4 strin into UCS-4 garray
  3152.      *
  3153.      * @throws   Exception
  3154.      * @access   private
  3155.      */
  3156.     private function _ucs4_string_to_ucs4($input)
  3157.     {
  3158.         $output = array();
  3159.  
  3160.         $inp_len strlen($input);
  3161.         // Input length must be dividable by 4
  3162.         if ($inp_len % 4{
  3163.             throw new Exception('Input UCS4 string is broken');
  3164.             return false;
  3165.         }
  3166.  
  3167.         // Empty input - return empty output
  3168.         if (!$inp_lenreturn $output;
  3169.  
  3170.         for ($i = 0$out_len = -1; $i $inp_len; ++$i{
  3171.             // Increment output position every 4 input bytes
  3172.             if (!$i % 4{
  3173.                 $out_len++;
  3174.                 $output[$out_len= 0;
  3175.             }
  3176.             $output[$out_len+= ord($input{$i}<< (8 * (3 - ($i % 4) ) );
  3177.         }
  3178.         return $output;
  3179.     }
  3180.  
  3181.     /**
  3182.      * Echo hex representation of UCS4 sequence.
  3183.      *
  3184.      * @param    array      $input       UCS4 sequence
  3185.      * @param    boolean    $include_bit Include bitmask in output
  3186.      * @return   void 
  3187.      * @static
  3188.      * @access   private
  3189.      */
  3190.     private static function _showHex($input$include_bit = false)
  3191.     {
  3192.         foreach ($input as $k => $v{
  3193.             echo '['$k'] => 'sprintf('%X'$v);
  3194.  
  3195.             if ($include_bit{
  3196.                 echo ' ('Net_IDNA::_showBitmask($v)')';
  3197.             }
  3198.  
  3199.             echo "\n";
  3200.         }
  3201.     }
  3202.  
  3203.     /**
  3204.      * Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits)
  3205.      * Output width is automagically determined
  3206.      *
  3207.      * @static
  3208.      * @access   private
  3209.      */
  3210.     private static function _showBitmask($octet)
  3211.     {
  3212.         if ($octet >= (1 << 16)) {
  3213.             $w = 31;
  3214.         else if ($octet >= (1 << 8)) {
  3215.             $w = 15;
  3216.         else {
  3217.             $w = 7;
  3218.         }
  3219.  
  3220.         $return '';
  3221.  
  3222.         for ($i $w$i > -1; $i--{
  3223.             $return .= ($octet (1 << $i))? 1 : '0';
  3224.         }
  3225.  
  3226.         return $return;
  3227.     }
  3228.     // }}}}
  3229. }
  3230.  
  3231. ?>

Documentation generated on Mon, 11 Mar 2019 14:15:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.