WordPress.org

Make WordPress Core

Changeset 41043


Ignore:
Timestamp:
07/14/17 05:46:19 (3 months ago)
Author:
pento
Message:

Emoji: Port the Twemoji regex to PHP.

Previously, wp_encode_emoji() and wp_staticize_emoji() used inaccurate regular expressions to find emoji, and transform then into HTML entities or <img>s, respectively. This would result in emoji not being correctly transformed, or occasionally, non-emoji being incorrectly transformed.

This commit adds a new grunt task - grunt precommit:emoji. It finds the regex in twemoji.js, transforms it into a PHP-friendly version, and adds it to formatting.php. This task is also automatically run by grunt precommit, when it detects that twemoji.js has changed.

The new regex requires features introduced in PCRE 8.32, which was introduced in PHP 5.4.14, though it was also backported to later releases of the PHP 5.3 series. For versions of PHP that don't support this, it will fall back to an updated version of the loose-matching regex.

For short posts, the performance difference between the old and new regex is negligible. As the posts get longer, however, the new method is exponentially faster.

Fixes #35293.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Gruntfile.js

    r40810 r41043  
    608608            } 
    609609        }, 
     610        replace: { 
     611            emojiRegex: { 
     612                options: { 
     613                    patterns: [ 
     614                        { 
     615                            match: /\/\/ START: emoji regex[\S\s]*\/\/ END: emoji regex/g, 
     616                            replacement: function () { 
     617                                var twemoji = grunt.file.read( SOURCE_DIR + 'wp-includes/js/twemoji.js' ), 
     618                                    found = twemoji.match( /re = \/(.*)\/g,/ ), 
     619                                    emojiRegex = found[1], 
     620                                    regex = '', 
     621                                    entities = ''; 
     622 
     623                                /* 
     624                                 * Twemoji does some nifty regex optimisations, splitting up surrogate pairs unit, searching by 
     625                                 * ranges of individual units, and compressing sets of individual units. This is super useful for 
     626                                 * reducing the size of the regex. 
     627                                 * 
     628                                 * Unfortunately, PCRE doesn't allow regexes to search for individual units, so we can't just 
     629                                 * blindly copy the Twemoji regex. 
     630                                 * 
     631                                 * The good news is, we don't have to worry about size restrictions, so we can just unravel the 
     632                                 * entire regex, and convert it to a PCRE-friendly format. 
     633                                 */ 
     634 
     635                                // Convert ranges: "\udc68-\udc6a" becomes "\udc68\udc69\udc6a". 
     636                                emojiRegex = emojiRegex.replace( /(\\u\w{4})\-(\\u\w{4})/g, function ( match, first, last ) { 
     637                                    var start = parseInt( first.substr( 2 ), 16 ); 
     638                                    var end = parseInt( last.substr( 2 ), 16 ); 
     639 
     640                                    var replace = ''; 
     641 
     642                                    for( var counter = start; counter <= end; counter++ ) { 
     643                                        replace += '\\u' + counter.toString( 16 ); 
     644                                    } 
     645 
     646                                    return replace; 
     647                                } ); 
     648 
     649                                // Convert sets: "\u200d[\u2640\u2642]\ufe0f" becomes "\u200d\u2640\ufe0f|\u200d\u2642\ufe0f". 
     650                                emojiRegex = emojiRegex.replace( /((?:\\u\w{4})*)\[((?:\\u\w{4})+)\]((?:\\u\w{4})*)/g, function ( match, before, middle, after ) { 
     651                                    //return params[1].split( '\\u' ).join( '|' + params[0] + '\\u' ).substr( 1 ); 
     652                                    if ( ! before && ! after ) { 
     653                                        return match; 
     654                                    } 
     655                                    var set = middle.match( /.{1,6}/g ); 
     656 
     657                                    return before + set.join( after + '|' + before ) + after; 
     658                                } ); 
     659 
     660                                // Convert surrogate pairs to their equivalent unicode scalar: "\ud83d\udc68" becomes "\u1f468". 
     661                                emojiRegex = emojiRegex.replace( /(\\ud[89a-f][0-9a-f]{2})(\\ud[89a-f][0-9a-f]{2})/g, function ( match, first, second ) { 
     662                                    var high = parseInt( first.substr( 2 ), 16 ); 
     663                                    var low = parseInt( second.substr( 2 ), 16 ); 
     664 
     665                                    var scalar = ( ( high - 0xD800 ) * 0x400 ) + ( low - 0xDC00 ) + 0x10000; 
     666 
     667                                    return '\\u' + scalar.toString( 16 ); 
     668                                } ); 
     669 
     670                                // Convert JavaScript-style code points to PHP-style: "\u1f468" becomes "\x{1f468}". 
     671                                emojiRegex = emojiRegex.replace( /\\u(\w+)/g, '\\x{$1}' ); 
     672 
     673                                // Convert PHP-style code points to HTML entities: "\x{1f468}" becomes "&#x1f468;". 
     674                                entities = emojiRegex.replace( /\\x{(\w+)}/g, '&#x$1;' ); 
     675                                entities = entities.replace( /\[([^\]]+)\]/g, function( match, codepoint ) { 
     676                                    return '(?:' + codepoint.replace( /;&/g, ';|&' ) + ')'; 
     677                                } ); 
     678 
     679                                regex += '// START: emoji regex\n'; 
     680                                regex += '\t$codepoints = \'/(' + emojiRegex + ')/u\';\n'; 
     681                                regex += '\t$entities = \'/(' + entities + ')/u\';\n'; 
     682                                regex += '\t// END: emoji regex'; 
     683 
     684                                return regex; 
     685                            } 
     686                        } 
     687                    ] 
     688                }, 
     689                files: [ 
     690                    { 
     691                        expand: true, 
     692                        flatten: true, 
     693                        src: [ 
     694                            SOURCE_DIR + 'wp-includes/formatting.php' 
     695                        ], 
     696                        dest: SOURCE_DIR + 'wp-includes/' 
     697                    } 
     698                ] 
     699            } 
     700        }, 
    610701        _watch: { 
    611702            all: { 
     
    719810    ] ); 
    720811 
     812    grunt.registerTask( 'precommit:emoji', [ 
     813        'replace:emojiRegex' 
     814    ] ); 
     815 
    721816    grunt.registerTask( 'precommit', 'Runs test and build tasks in preparation for a commit', function() { 
    722817        var done = this.async(); 
     
    784879                        } 
    785880                    } ); 
     881 
     882                    if ( [ 'twemoji.js' ].some( testPath ) ) { 
     883                        grunt.log.writeln( 'twemoji.js has updated. Running `precommit:emoji.' ); 
     884                        taskList.push( 'precommit:emoji' ); 
     885                    } 
    786886                } 
    787887 
  • trunk/package.json

    r40871 r41043  
    3131    "grunt-patch-wordpress": "~0.4.2", 
    3232    "grunt-postcss": "~0.7.1", 
     33    "grunt-replace": "~1.0.1", 
    3334    "grunt-rtlcss": "~2.0.1", 
    3435    "grunt-sass": "~1.2.1", 
  • trunk/src/wp-includes/formatting.php

    r41014 r41043  
    50955095 
    50965096/** 
    5097  * Convert any 4 byte emoji in a string to their equivalent HTML entity. 
    5098  * 
    5099  * Currently, only Unicode 7 emoji are supported. Skin tone modifiers are allowed, 
    5100  * all other Unicode 8 emoji will be added when the spec is finalised. 
     5097 * Convert emoji characters to their equivalent HTML entity. 
    51015098 * 
    51025099 * This allows us to store emoji in a DB using the utf8 character set. 
     
    51095106function wp_encode_emoji( $content ) { 
    51105107    if ( function_exists( 'mb_convert_encoding' ) ) { 
    5111         $regex = '/( 
    5112              \x23\xE2\x83\xA3               # Digits 
    5113              [\x30-\x39]\xE2\x83\xA3 
    5114            | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters 
    5115            | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc 
    5116            | \xF0\x9F\x98[\x80-\xBF]        # Smilies 
    5117            | \xF0\x9F\x99[\x80-\x8F] 
    5118            | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols 
    5119         )/x'; 
     5108        $regex = wp_emoji_regex( 'codepoints' ); 
    51205109 
    51215110        $matches = array(); 
    51225111        if ( preg_match_all( $regex, $content, $matches ) ) { 
    51235112            if ( ! empty( $matches[1] ) ) { 
    5124                 foreach ( $matches[1] as $emoji ) { 
     5113                foreach ( array_unique( $matches[1] ) as $emoji ) { 
    51255114                    /* 
    51265115                     * UTF-32's hex encoding is the same as HTML's hex encoding. 
    51275116                     * So, by converting the emoji from UTF-8 to UTF-32, we magically 
    5128                      * get the correct hex encoding. 
     5117                     * get the correct hex encoding, 0 padded to 8 characters. 
    51295118                     */ 
    51305119                    $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) ); 
    51315120                    if ( isset( $unpacked[1] ) ) { 
    5132                         $entity = '&#x' . ltrim( $unpacked[1], '0' ) . ';'; 
     5121                        $parts = str_split( $unpacked[1], 8 ); 
     5122                        $entity = ''; 
     5123 
     5124                        foreach ( $parts as $part ) { 
     5125                            $entity .= '&#x' . ltrim( $part, '0' ) . ';'; 
     5126                        } 
     5127 
    51335128                        $content = str_replace( $emoji, $entity, $content ); 
    51345129                    } 
     
    51525147    $text = wp_encode_emoji( $text ); 
    51535148 
    5154     /** This filter is documented in wp-includes/formatting.php */ 
    5155     $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.3/72x72/' ); 
    5156  
    5157     /** This filter is documented in wp-includes/formatting.php */ 
    5158     $ext = apply_filters( 'emoji_ext', '.png' ); 
    5159  
    51605149    $output = ''; 
    51615150    /* 
     
    51725161    $ignore_block_element = ''; 
    51735162 
     5163    $regex = wp_emoji_regex( 'entities' ); 
     5164 
    51745165    for ( $i = 0; $i < $stop; $i++ ) { 
    51755166        $content = $textarr[$i]; 
     
    51825173        // If it's not a tag and not in ignore block. 
    51835174        if ( '' ==  $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) { 
    5184             $matches = array(); 
    5185             if ( preg_match_all( '/(&#x1f1(e[6-9a-f]|f[0-9a-f]);){2}/', $content, $matches ) ) { 
    5186                 if ( ! empty( $matches[0] ) ) { 
    5187                     foreach ( $matches[0] as $flag ) { 
    5188                         $chars = str_replace( array( '&#x', ';'), '', $flag ); 
    5189  
    5190                         list( $char1, $char2 ) = str_split( $chars, 5 ); 
    5191                         $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char1 . '-' . $char2 . $ext, html_entity_decode( $flag ) ); 
    5192  
    5193                         $content = str_replace( $flag, $entity, $content ); 
    5194                     } 
    5195                 } 
    5196             } 
    5197  
    5198             // Loosely match the Emoji Unicode range. 
    5199             $regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/'; 
    5200  
    5201             $matches = array(); 
    5202             if ( preg_match_all( $regex, $content, $matches ) ) { 
    5203                 if ( ! empty( $matches[1] ) ) { 
    5204                     foreach ( $matches[1] as $emoji ) { 
    5205                         $char = str_replace( array( '&#x', ';'), '', $emoji ); 
    5206                         $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char . $ext, html_entity_decode( $emoji ) ); 
    5207  
    5208                         $content = str_replace( $emoji, $entity, $content ); 
    5209                     } 
    5210                 } 
    5211             } 
     5175            $content = preg_replace_callback( $regex, '_wp_staticize_emoji', $content ); 
    52125176        } 
    52135177 
     
    52215185 
    52225186    return $output; 
     5187} 
     5188 
     5189/** 
     5190 * Callback for wp_staticize_emoji() to turn matched emoji glyphs into images. 
     5191 * 
     5192 * @since 4.8.1 
     5193 * @access private 
     5194 * 
     5195 * @param  array $matches The matched data. 
     5196 * @return string HTML for the static emoji image. 
     5197 */ 
     5198function _wp_staticize_emoji( $matches ) { 
     5199    /** This filter is documented in wp-includes/formatting.php */ 
     5200    $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.3/72x72/' ); 
     5201 
     5202    /** This filter is documented in wp-includes/formatting.php */ 
     5203    $ext = apply_filters( 'emoji_ext', '.png' ); 
     5204 
     5205    $char = str_replace( ';&#x', '-', $matches[1] ); 
     5206    $char = str_replace( array( '&#x', ';'), '', $char ); 
     5207 
     5208    return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char . $ext, html_entity_decode( $matches[1] ) ); 
    52235209} 
    52245210 
     
    52915277 
    52925278/** 
     5279 * Returns a regex string to match all emoji that WordPress recognises. 
     5280 * 
     5281 * This regex is automatically built from the regex in twemoji.js - if it needs to be updated, 
     5282 * you should update the regex there, then run the `grunt precommit:emoji` job. 
     5283 * 
     5284 * @since 4.8.1 
     5285 * 
     5286 * @param string $type Optional. Which regex type to return. Accepts 'codepoints' or 'entities', default 'coidepoints'. 
     5287 * @return string A regex to match all emoji that WordPress recognises. 
     5288 */ 
     5289function wp_emoji_regex( $type = 'codepoints' ) { 
     5290    // If we're using a PCRE version that doesn't support Unicode, return a loose match regex. 
     5291    if ( 'codepoints' === $type && ( ! defined( 'PCRE_VERSION' ) || version_compare( PCRE_VERSION, '8.32', '<=' ) ) ) { 
     5292        return '/( 
     5293             \xE2\x98[\x80-\xFF]            # Symbols 
     5294           | \xE2\x99[\x00-\xFF] 
     5295           | [\xE3-\xED][\x00-\xFF]{2} 
     5296           | [\x23\x30-\x39]\xE2\x83\xA3    # Digits 
     5297           | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters 
     5298           | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc 
     5299           | \xF0\x9F\x98[\x80-\xBF]        # Smilies 
     5300           | \xF0\x9F\x99[\x80-\x8F] 
     5301           | \xF0\x9F[\xA4-\xA7][\x00-\xFF] 
     5302           | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols 
     5303           | \xE2\x80\x8D                   # Zero Width Joiner 
     5304           | \xEF\xB8\x8F                   # Emoji Variation Selector 
     5305        )/x'; 
     5306    } 
     5307 
     5308    // Do not remove the START/END comments - they're used to find where to insert the regex. 
     5309 
     5310    // START: emoji regex 
     5311    $codepoints = '/(\x{1f468}|\x{1f469}(?:\x{1f3fb}|\x{1f3fc}|\x{1f3fd}|\x{1f3fe}|\x{1f3ff})?\x{200d}(?:\x{2695}\x{fe0f}|\x{2696}\x{fe0f}|\x{2708}\x{fe0f}|\x{1f33e}|\x{1f373}|\x{1f393}|\x{1f3a4}|\x{1f3a8}|\x{1f3eb}|\x{1f3ed}|\x{1f4bb}|\x{1f4bc}|\x{1f527}|\x{1f52c}|\x{1f680}|\x{1f692})|(?:\x{1f3cb}|\x{1f3cc}|\x{1f575}|\x{26f9})(?:\x{fe0f}|\x{1f3fb}|\x{1f3fc}|\x{1f3fd}|\x{1f3fe}|\x{1f3ff})\x{200d}\x{2640}\x{fe0f}|\x{200d}\x{2642}\x{fe0f}|(?:\x{1f3c3}|\x{1f3c4}|\x{1f3ca}|\x{1f46e}|\x{1f471}|\x{1f473}|\x{1f477}|\x{1f481}|\x{1f482}|\x{1f486}|\x{1f487}|\x{1f645}|\x{1f646}|\x{1f647}|\x{1f64b}|\x{1f64d}|\x{1f64e}|\x{1f6a3}|\x{1f6b4}|\x{1f6b5}|\x{1f6b6}|\x{1f926}|\x{1f937}|\x{1f938}|\x{1f939}|\x{1f93d}|\x{1f93e}|\x{1f9d6}|\x{1f9d7}|\x{1f9d8}|\x{1f9d9}|\x{1f9da}|\x{1f9db}|\x{1f9dc}|\x{1f9dd})(?:\x{1f3fb}|\x{1f3fc}|\x{1f3fd}|\x{1f3fe}|\x{1f3ff})?\x{200d}\x{2640}\x{fe0f}|\x{200d}\x{2642}\x{fe0f}|\x{1f468}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f48b}\x{200d}\x{1f468}|\x{1f468}\x{200d}\x{1f468}\x{200d}\x{1f466}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f468}\x{200d}\x{1f467}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f468}\x{200d}\x{1f467}\x{200d}\x{1f467}|\x{1f468}\x{200d}\x{1f469}\x{200d}\x{1f466}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f467}|\x{1f469}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f48b}\x{200d}\x{1f468}|\x{1f469}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f48b}\x{200d}\x{1f469}|\x{1f469}\x{200d}\x{1f469}\x{200d}\x{1f466}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f467}|\x{1f468}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f468}|\x{1f468}\x{200d}\x{1f466}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f467}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f467}\x{200d}\x{1f467}|\x{1f468}\x{200d}\x{1f468}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f468}\x{200d}\x{1f467}|\x{1f468}\x{200d}\x{1f469}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f469}\x{200d}\x{1f467}|\x{1f469}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f468}|\x{1f469}\x{200d}\x{2764}\x{fe0f}\x{200d}\x{1f469}|\x{1f469}\x{200d}\x{1f466}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f467}\x{200d}\x{1f467}|\x{1f469}\x{200d}\x{1f469}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f469}\x{200d}\x{1f467}|\x{1f3f3}\x{fe0f}\x{200d}\x{1f308}|\x{1f3f4}\x{200d}\x{2620}\x{fe0f}|\x{1f441}\x{200d}\x{1f5e8}|\x{1f468}\x{200d}\x{1f466}|\x{1f468}\x{200d}\x{1f467}|\x{1f469}\x{200d}\x{1f466}|\x{1f469}\x{200d}\x{1f467}|\x{1f46f}\x{200d}\x{2640}\x{fe0f}|\x{1f46f}\x{200d}\x{2642}\x{fe0f}|\x{1f93c}\x{200d}\x{2640}\x{fe0f}|\x{1f93c}\x{200d}\x{2642}\x{fe0f}|\x{1f9de}\x{200d}\x{2640}\x{fe0f}|\x{1f9de}\x{200d}\x{2642}\x{fe0f}|\x{1f9df}\x{200d}\x{2640}\x{fe0f}|\x{1f9df}\x{200d}\x{2642}\x{fe0f}|(?:[\x{0023}\x{002a}\x{30}\x{31}\x{32}\x{33}\x{34}\x{35}\x{36}\x{37}\x{38}\x{39}])\x{fe0f}?\x{20e3}|(?:(?:\x{1f3cb}|\x{1f3cc}|\x{1f574}|\x{1f575}|\x{1f590}|[\x{261d}\x{26f7}\x{26f9}\x{270c}\x{270d}])(?:\x{fe0f}|(?!\x{fe0e}))|\x{1f385}|\x{1f3c2}|\x{1f3c3}|\x{1f3c4}|\x{1f3c7}|\x{1f3ca}|\x{1f442}|\x{1f443}|\x{1f446}|\x{1f447}|\x{1f448}|\x{1f449}|\x{1f44a}|\x{1f44b}|\x{1f44c}|\x{1f44d}|\x{1f44e}|\x{1f44f}|\x{1f450}|\x{1f466}|\x{1f467}|\x{1f468}|\x{1f469}|\x{1f46e}|\x{1f470}|\x{1f471}|\x{1f472}|\x{1f473}|\x{1f474}|\x{1f475}|\x{1f476}|\x{1f477}|\x{1f478}|\x{1f47c}|\x{1f481}|\x{1f482}|\x{1f483}|\x{1f485}|\x{1f486}|\x{1f487}|\x{1f4aa}|\x{1f57a}|\x{1f595}|\x{1f596}|\x{1f645}|\x{1f646}|\x{1f647}|\x{1f64b}|\x{1f64c}|\x{1f64d}|\x{1f64e}|\x{1f64f}|\x{1f6a3}|\x{1f6b4}|\x{1f6b5}|\x{1f6b6}|\x{1f6c0}|\x{1f6cc}|\x{1f918}|\x{1f919}|\x{1f91a}|\x{1f91b}|\x{1f91c}|\x{1f91e}|\x{1f91f}|\x{1f926}|\x{1f930}|\x{1f931}|\x{1f932}|\x{1f933}|\x{1f934}|\x{1f935}|\x{1f936}|\x{1f937}|\x{1f938}|\x{1f939}|\x{1f93d}|\x{1f93e}|\x{1f9d1}|\x{1f9d2}|\x{1f9d3}|\x{1f9d4}|\x{1f9d5}|\x{1f9d6}|\x{1f9d7}|\x{1f9d8}|\x{1f9d9}|\x{1f9da}|\x{1f9db}|\x{1f9dc}|\x{1f9dd}|[\x{270a}\x{270b}])(?:\x{1f3fb}|\x{1f3fc}|\x{1f3fd}|\x{1f3fe}|\x{1f3ff}|)|\x{1f3f4}\x{e0067}\x{e0062}\x{e0065}\x{e006e}\x{e0067}\x{e007f}|\x{1f3f4}\x{e0067}\x{e0062}\x{e0073}\x{e0063}\x{e0074}\x{e007f}|\x{1f3f4}\x{e0067}\x{e0062}\x{e0077}\x{e006c}\x{e0073}\x{e007f}|\x{1f1e6}\x{1f1e8}|\x{1f1e6}\x{1f1e9}|\x{1f1e6}\x{1f1ea}|\x{1f1e6}\x{1f1eb}|\x{1f1e6}\x{1f1ec}|\x{1f1e6}\x{1f1ee}|\x{1f1e6}\x{1f1f1}|\x{1f1e6}\x{1f1f2}|\x{1f1e6}\x{1f1f4}|\x{1f1e6}\x{1f1f6}|\x{1f1e6}\x{1f1f7}|\x{1f1e6}\x{1f1f8}|\x{1f1e6}\x{1f1f9}|\x{1f1e6}\x{1f1fa}|\x{1f1e6}\x{1f1fc}|\x{1f1e6}\x{1f1fd}|\x{1f1e6}\x{1f1ff}|\x{1f1e7}\x{1f1e6}|\x{1f1e7}\x{1f1e7}|\x{1f1e7}\x{1f1e9}|\x{1f1e7}\x{1f1ea}|\x{1f1e7}\x{1f1eb}|\x{1f1e7}\x{1f1ec}|\x{1f1e7}\x{1f1ed}|\x{1f1e7}\x{1f1ee}|\x{1f1e7}\x{1f1ef}|\x{1f1e7}\x{1f1f1}|\x{1f1e7}\x{1f1f2}|\x{1f1e7}\x{1f1f3}|\x{1f1e7}\x{1f1f4}|\x{1f1e7}\x{1f1f6}|\x{1f1e7}\x{1f1f7}|\x{1f1e7}\x{1f1f8}|\x{1f1e7}\x{1f1f9}|\x{1f1e7}\x{1f1fb}|\x{1f1e7}\x{1f1fc}|\x{1f1e7}\x{1f1fe}|\x{1f1e7}\x{1f1ff}|\x{1f1e8}\x{1f1e6}|\x{1f1e8}\x{1f1e8}|\x{1f1e8}\x{1f1e9}|\x{1f1e8}\x{1f1eb}|\x{1f1e8}\x{1f1ec}|\x{1f1e8}\x{1f1ed}|\x{1f1e8}\x{1f1ee}|\x{1f1e8}\x{1f1f0}|\x{1f1e8}\x{1f1f1}|\x{1f1e8}\x{1f1f2}|\x{1f1e8}\x{1f1f3}|\x{1f1e8}\x{1f1f4}|\x{1f1e8}\x{1f1f5}|\x{1f1e8}\x{1f1f7}|\x{1f1e8}\x{1f1fa}|\x{1f1e8}\x{1f1fb}|\x{1f1e8}\x{1f1fc}|\x{1f1e8}\x{1f1fd}|\x{1f1e8}\x{1f1fe}|\x{1f1e8}\x{1f1ff}|\x{1f1e9}\x{1f1ea}|\x{1f1e9}\x{1f1ec}|\x{1f1e9}\x{1f1ef}|\x{1f1e9}\x{1f1f0}|\x{1f1e9}\x{1f1f2}|\x{1f1e9}\x{1f1f4}|\x{1f1e9}\x{1f1ff}|\x{1f1ea}\x{1f1e6}|\x{1f1ea}\x{1f1e8}|\x{1f1ea}\x{1f1ea}|\x{1f1ea}\x{1f1ec}|\x{1f1ea}\x{1f1ed}|\x{1f1ea}\x{1f1f7}|\x{1f1ea}\x{1f1f8}|\x{1f1ea}\x{1f1f9}|\x{1f1ea}\x{1f1fa}|\x{1f1eb}\x{1f1ee}|\x{1f1eb}\x{1f1ef}|\x{1f1eb}\x{1f1f0}|\x{1f1eb}\x{1f1f2}|\x{1f1eb}\x{1f1f4}|\x{1f1eb}\x{1f1f7}|\x{1f1ec}\x{1f1e6}|\x{1f1ec}\x{1f1e7}|\x{1f1ec}\x{1f1e9}|\x{1f1ec}\x{1f1ea}|\x{1f1ec}\x{1f1eb}|\x{1f1ec}\x{1f1ec}|\x{1f1ec}\x{1f1ed}|\x{1f1ec}\x{1f1ee}|\x{1f1ec}\x{1f1f1}|\x{1f1ec}\x{1f1f2}|\x{1f1ec}\x{1f1f3}|\x{1f1ec}\x{1f1f5}|\x{1f1ec}\x{1f1f6}|\x{1f1ec}\x{1f1f7}|\x{1f1ec}\x{1f1f8}|\x{1f1ec}\x{1f1f9}|\x{1f1ec}\x{1f1fa}|\x{1f1ec}\x{1f1fc}|\x{1f1ec}\x{1f1fe}|\x{1f1ed}\x{1f1f0}|\x{1f1ed}\x{1f1f2}|\x{1f1ed}\x{1f1f3}|\x{1f1ed}\x{1f1f7}|\x{1f1ed}\x{1f1f9}|\x{1f1ed}\x{1f1fa}|\x{1f1ee}\x{1f1e8}|\x{1f1ee}\x{1f1e9}|\x{1f1ee}\x{1f1ea}|\x{1f1ee}\x{1f1f1}|\x{1f1ee}\x{1f1f2}|\x{1f1ee}\x{1f1f3}|\x{1f1ee}\x{1f1f4}|\x{1f1ee}\x{1f1f6}|\x{1f1ee}\x{1f1f7}|\x{1f1ee}\x{1f1f8}|\x{1f1ee}\x{1f1f9}|\x{1f1ef}\x{1f1ea}|\x{1f1ef}\x{1f1f2}|\x{1f1ef}\x{1f1f4}|\x{1f1ef}\x{1f1f5}|\x{1f1f0}\x{1f1ea}|\x{1f1f0}\x{1f1ec}|\x{1f1f0}\x{1f1ed}|\x{1f1f0}\x{1f1ee}|\x{1f1f0}\x{1f1f2}|\x{1f1f0}\x{1f1f3}|\x{1f1f0}\x{1f1f5}|\x{1f1f0}\x{1f1f7}|\x{1f1f0}\x{1f1fc}|\x{1f1f0}\x{1f1fe}|\x{1f1f0}\x{1f1ff}|\x{1f1f1}\x{1f1e6}|\x{1f1f1}\x{1f1e7}|\x{1f1f1}\x{1f1e8}|\x{1f1f1}\x{1f1ee}|\x{1f1f1}\x{1f1f0}|\x{1f1f1}\x{1f1f7}|\x{1f1f1}\x{1f1f8}|\x{1f1f1}\x{1f1f9}|\x{1f1f1}\x{1f1fa}|\x{1f1f1}\x{1f1fb}|\x{1f1f1}\x{1f1fe}|\x{1f1f2}\x{1f1e6}|\x{1f1f2}\x{1f1e8}|\x{1f1f2}\x{1f1e9}|\x{1f1f2}\x{1f1ea}|\x{1f1f2}\x{1f1eb}|\x{1f1f2}\x{1f1ec}|\x{1f1f2}\x{1f1ed}|\x{1f1f2}\x{1f1f0}|\x{1f1f2}\x{1f1f1}|\x{1f1f2}\x{1f1f2}|\x{1f1f2}\x{1f1f3}|\x{1f1f2}\x{1f1f4}|\x{1f1f2}\x{1f1f5}|\x{1f1f2}\x{1f1f6}|\x{1f1f2}\x{1f1f7}|\x{1f1f2}\x{1f1f8}|\x{1f1f2}\x{1f1f9}|\x{1f1f2}\x{1f1fa}|\x{1f1f2}\x{1f1fb}|\x{1f1f2}\x{1f1fc}|\x{1f1f2}\x{1f1fd}|\x{1f1f2}\x{1f1fe}|\x{1f1f2}\x{1f1ff}|\x{1f1f3}\x{1f1e6}|\x{1f1f3}\x{1f1e8}|\x{1f1f3}\x{1f1ea}|\x{1f1f3}\x{1f1eb}|\x{1f1f3}\x{1f1ec}|\x{1f1f3}\x{1f1ee}|\x{1f1f3}\x{1f1f1}|\x{1f1f3}\x{1f1f4}|\x{1f1f3}\x{1f1f5}|\x{1f1f3}\x{1f1f7}|\x{1f1f3}\x{1f1fa}|\x{1f1f3}\x{1f1ff}|\x{1f1f4}\x{1f1f2}|\x{1f1f5}\x{1f1e6}|\x{1f1f5}\x{1f1ea}|\x{1f1f5}\x{1f1eb}|\x{1f1f5}\x{1f1ec}|\x{1f1f5}\x{1f1ed}|\x{1f1f5}\x{1f1f0}|\x{1f1f5}\x{1f1f1}|\x{1f1f5}\x{1f1f2}|\x{1f1f5}\x{1f1f3}|\x{1f1f5}\x{1f1f7}|\x{1f1f5}\x{1f1f8}|\x{1f1f5}\x{1f1f9}|\x{1f1f5}\x{1f1fc}|\x{1f1f5}\x{1f1fe}|\x{1f1f6}\x{1f1e6}|\x{1f1f7}\x{1f1ea}|\x{1f1f7}\x{1f1f4}|\x{1f1f7}\x{1f1f8}|\x{1f1f7}\x{1f1fa}|\x{1f1f7}\x{1f1fc}|\x{1f1f8}\x{1f1e6}|\x{1f1f8}\x{1f1e7}|\x{1f1f8}\x{1f1e8}|\x{1f1f8}\x{1f1e9}|\x{1f1f8}\x{1f1ea}|\x{1f1f8}\x{1f1ec}|\x{1f1f8}\x{1f1ed}|\x{1f1f8}\x{1f1ee}|\x{1f1f8}\x{1f1ef}|\x{1f1f8}\x{1f1f0}|\x{1f1f8}\x{1f1f1}|\x{1f1f8}\x{1f1f2}|\x{1f1f8}\x{1f1f3}|\x{1f1f8}\x{1f1f4}|\x{1f1f8}\x{1f1f7}|\x{1f1f8}\x{1f1f8}|\x{1f1f8}\x{1f1f9}|\x{1f1f8}\x{1f1fb}|\x{1f1f8}\x{1f1fd}|\x{1f1f8}\x{1f1fe}|\x{1f1f8}\x{1f1ff}|\x{1f1f9}\x{1f1e6}|\x{1f1f9}\x{1f1e8}|\x{1f1f9}\x{1f1e9}|\x{1f1f9}\x{1f1eb}|\x{1f1f9}\x{1f1ec}|\x{1f1f9}\x{1f1ed}|\x{1f1f9}\x{1f1ef}|\x{1f1f9}\x{1f1f0}|\x{1f1f9}\x{1f1f1}|\x{1f1f9}\x{1f1f2}|\x{1f1f9}\x{1f1f3}|\x{1f1f9}\x{1f1f4}|\x{1f1f9}\x{1f1f7}|\x{1f1f9}\x{1f1f9}|\x{1f1f9}\x{1f1fb}|\x{1f1f9}\x{1f1fc}|\x{1f1f9}\x{1f1ff}|\x{1f1fa}\x{1f1e6}|\x{1f1fa}\x{1f1ec}|\x{1f1fa}\x{1f1f2}|\x{1f1fa}\x{1f1f3}|\x{1f1fa}\x{1f1f8}|\x{1f1fa}\x{1f1fe}|\x{1f1fa}\x{1f1ff}|\x{1f1fb}\x{1f1e6}|\x{1f1fb}\x{1f1e8}|\x{1f1fb}\x{1f1ea}|\x{1f1fb}\x{1f1ec}|\x{1f1fb}\x{1f1ee}|\x{1f1fb}\x{1f1f3}|\x{1f1fb}\x{1f1fa}|\x{1f1fc}\x{1f1eb}|\x{1f1fc}\x{1f1f8}|\x{1f1fd}\x{1f1f0}|\x{1f1fe}\x{1f1ea}|\x{1f1fe}\x{1f1f9}|\x{1f1ff}\x{1f1e6}|\x{1f1ff}\x{1f1f2}|\x{1f1ff}\x{1f1fc}|\x{10000}|\x{1f0cf}|\x{1f18e}|\x{1f191}|\x{1f192}|\x{1f193}|\x{1f194}|\x{1f195}|\x{1f196}|\x{1f197}|\x{1f198}|\x{1f199}|\x{1f19a}|\x{1f1e6}|\x{1f1e7}|\x{1f1e8}|\x{1f1e9}|\x{1f1ea}|\x{1f1eb}|\x{1f1ec}|\x{1f1ed}|\x{1f1ee}|\x{1f1ef}|\x{1f1f0}|\x{1f1f1}|\x{1f1f2}|\x{1f1f3}|\x{1f1f4}|\x{1f1f5}|\x{1f1f6}|\x{1f1f7}|\x{1f1f8}|\x{1f1f9}|\x{1f1fa}|\x{1f1fb}|\x{1f1fc}|\x{1f1fd}|\x{1f1fe}|\x{1f1ff}|\x{1f201}|\x{1f232}|\x{1f233}|\x{1f234}|\x{1f235}|\x{1f236}|\x{1f238}|\x{1f239}|\x{1f23a}|\x{1f250}|\x{1f251}|\x{1f300}|\x{1f301}|\x{1f302}|\x{1f303}|\x{1f304}|\x{1f305}|\x{1f306}|\x{1f307}|\x{1f308}|\x{1f309}|\x{1f30a}|\x{1f30b}|\x{1f30c}|\x{1f30d}|\x{1f30e}|\x{1f30f}|\x{1f310}|\x{1f311}|\x{1f312}|\x{1f313}|\x{1f314}|\x{1f315}|\x{1f316}|\x{1f317}|\x{1f318}|\x{1f319}|\x{1f31a}|\x{1f31b}|\x{1f31c}|\x{1f31d}|\x{1f31e}|\x{1f31f}|\x{1f320}|\x{1f32d}|\x{1f32e}|\x{1f32f}|\x{1f330}|\x{1f331}|\x{1f332}|\x{1f333}|\x{1f334}|\x{1f335}|\x{1f337}|\x{1f338}|\x{1f339}|\x{1f33a}|\x{1f33b}|\x{1f33c}|\x{1f33d}|\x{1f33e}|\x{1f33f}|\x{1f340}|\x{1f341}|\x{1f342}|\x{1f343}|\x{1f344}|\x{1f345}|\x{1f346}|\x{1f347}|\x{1f348}|\x{1f349}|\x{1f34a}|\x{1f34b}|\x{1f34c}|\x{1f34d}|\x{1f34e}|\x{1f34f}|\x{1f350}|\x{1f351}|\x{1f352}|\x{1f353}|\x{1f354}|\x{1f355}|\x{1f356}|\x{1f357}|\x{1f358}|\x{1f359}|\x{1f35a}|\x{1f35b}|\x{1f35c}|\x{1f35d}|\x{1f35e}|\x{1f35f}|\x{1f360}|\x{1f361}|\x{1f362}|\x{1f363}|\x{1f364}|\x{1f365}|\x{1f366}|\x{1f367}|\x{1f368}|\x{1f369}|\x{1f36a}|\x{1f36b}|\x{1f36c}|\x{1f36d}|\x{1f36e}|\x{1f36f}|\x{1f370}|\x{1f371}|\x{1f372}|\x{1f373}|\x{1f374}|\x{1f375}|\x{1f376}|\x{1f377}|\x{1f378}|\x{1f379}|\x{1f37a}|\x{1f37b}|\x{1f37c}|\x{1f37e}|\x{1f37f}|\x{1f380}|\x{1f381}|\x{1f382}|\x{1f383}|\x{1f384}|\x{1f386}|\x{1f387}|\x{1f388}|\x{1f389}|\x{1f38a}|\x{1f38b}|\x{1f38c}|\x{1f38d}|\x{1f38e}|\x{1f38f}|\x{1f390}|\x{1f391}|\x{1f392}|\x{1f393}|\x{1f3a0}|\x{1f3a1}|\x{1f3a2}|\x{1f3a3}|\x{1f3a4}|\x{1f3a5}|\x{1f3a6}|\x{1f3a7}|\x{1f3a8}|\x{1f3a9}|\x{1f3aa}|\x{1f3ab}|\x{1f3ac}|\x{1f3ad}|\x{1f3ae}|\x{1f3af}|\x{1f3b0}|\x{1f3b1}|\x{1f3b2}|\x{1f3b3}|\x{1f3b4}|\x{1f3b5}|\x{1f3b6}|\x{1f3b7}|\x{1f3b8}|\x{1f3b9}|\x{1f3ba}|\x{1f3bb}|\x{1f3bc}|\x{1f3bd}|\x{1f3be}|\x{1f3bf}|\x{1f3c0}|\x{1f3c1}|\x{1f3c5}|\x{1f3c6}|\x{1f3c8}|\x{1f3c9}|\x{1f3cf}|\x{1f3d0}|\x{1f3d1}|\x{1f3d2}|\x{1f3d3}|\x{1f3e0}|\x{1f3e1}|\x{1f3e2}|\x{1f3e3}|\x{1f3e4}|\x{1f3e5}|\x{1f3e6}|\x{1f3e7}|\x{1f3e8}|\x{1f3e9}|\x{1f3ea}|\x{1f3eb}|\x{1f3ec}|\x{1f3ed}|\x{1f3ee}|\x{1f3ef}|\x{1f3f0}|\x{1f3f4}|\x{1f3f8}|\x{1f3f9}|\x{1f3fa}|\x{1f3fb}|\x{1f3fc}|\x{1f3fd}|\x{1f3fe}|\x{1f3ff}|\x{1f400}|\x{1f401}|\x{1f402}|\x{1f403}|\x{1f404}|\x{1f405}|\x{1f406}|\x{1f407}|\x{1f408}|\x{1f409}|\x{1f40a}|\x{1f40b}|\x{1f40c}|\x{1f40d}|\x{1f40e}|\x{1f40f}|\x{1f410}|\x{1f411}|\x{1f412}|\x{1f413}|\x{1f414}|\x{1f415}|\x{1f416}|\x{1f417}|\x{1f418}|\x{1f419}|\x{1f41a}|\x{1f41b}|\x{1f41c}|\x{1f41d}|\x{1f41e}|\x{1f41f}|\x{1f420}|\x{1f421}|\x{1f422}|\x{1f423}|\x{1f424}|\x{1f425}|\x{1f426}|\x{1f427}|\x{1f428}|\x{1f429}|\x{1f42a}|\x{1f42b}|\x{1f42c}|\x{1f42d}|\x{1f42e}|\x{1f42f}|\x{1f430}|\x{1f431}|\x{1f432}|\x{1f433}|\x{1f434}|\x{1f435}|\x{1f436}|\x{1f437}|\x{1f438}|\x{1f439}|\x{1f43a}|\x{1f43b}|\x{1f43c}|\x{1f43d}|\x{1f43e}|\x{1f440}|\x{1f444}|\x{1f445}|\x{1f451}|\x{1f452}|\x{1f453}|\x{1f454}|\x{1f455}|\x{1f456}|\x{1f457}|\x{1f458}|\x{1f459}|\x{1f45a}|\x{1f45b}|\x{1f45c}|\x{1f45d}|\x{1f45e}|\x{1f45f}|\x{1f460}|\x{1f461}|\x{1f462}|\x{1f463}|\x{1f464}|\x{1f465}|\x{1f46a}|\x{1f46b}|\x{1f46c}|\x{1f46d}|\x{1f46f}|\x{1f479}|\x{1f47a}|\x{1f47b}|\x{1f47d}|\x{1f47e}|\x{1f47f}|\x{1f480}|\x{1f484}|\x{1f488}|\x{1f489}|\x{1f48a}|\x{1f48b}|\x{1f48c}|\x{1f48d}|\x{1f48e}|\x{1f48f}|\x{1f490}|\x{1f491}|\x{1f492}|\x{1f493}|\x{1f494}|\x{1f495}|\x{1f496}|\x{1f497}|\x{1f498}|\x{1f499}|\x{1f49a}|\x{1f49b}|\x{1f49c}|\x{1f49d}|\x{1f49e}|\x{1f49f}|\x{1f4a0}|\x{1f4a1}|\x{1f4a2}|\x{1f4a3}|\x{1f4a4}|\x{1f4a5}|\x{1f4a6}|\x{1f4a7}|\x{1f4a8}|\x{1f4a9}|\x{1f4ab}|\x{1f4ac}|\x{1f4ad}|\x{1f4ae}|\x{1f4af}|\x{1f4b0}|\x{1f4b1}|\x{1f4b2}|\x{1f4b3}|\x{1f4b4}|\x{1f4b5}|\x{1f4b6}|\x{1f4b7}|\x{1f4b8}|\x{1f4b9}|\x{1f4ba}|\x{1f4bb}|\x{1f4bc}|\x{1f4bd}|\x{1f4be}|\x{1f4bf}|\x{1f4c0}|\x{1f4c1}|\x{1f4c2}|\x{1f4c3}|\x{1f4c4}|\x{1f4c5}|\x{1f4c6}|\x{1f4c7}|\x{1f4c8}|\x{1f4c9}|\x{1f4ca}|\x{1f4cb}|\x{1f4cc}|\x{1f4cd}|\x{1f4ce}|\x{1f4cf}|\x{1f4d0}|\x{1f4d1}|\x{1f4d2}|\x{1f4d3}|\x{1f4d4}|\x{1f4d5}|\x{1f4d6}|\x{1f4d7}|\x{1f4d8}|\x{1f4d9}|\x{1f4da}|\x{1f4db}|\x{1f4dc}|\x{1f4dd}|\x{1f4de}|\x{1f4df}|\x{1f4e0}|\x{1f4e1}|\x{1f4e2}|\x{1f4e3}|\x{1f4e4}|\x{1f4e5}|\x{1f4e6}|\x{1f4e7}|\x{1f4e8}|\x{1f4e9}|\x{1f4ea}|\x{1f4eb}|\x{1f4ec}|\x{1f4ed}|\x{1f4ee}|\x{1f4ef}|\x{1f4f0}|\x{1f4f1}|\x{1f4f2}|\x{1f4f3}|\x{1f4f4}|\x{1f4f5}|\x{1f4f6}|\x{1f4f7}|\x{1f4f8}|\x{1f4f9}|\x{1f4fa}|\x{1f4fb}|\x{1f4fc}|\x{1f4ff}|\x{1f500}|\x{1f501}|\x{1f502}|\x{1f503}|\x{1f504}|\x{1f505}|\x{1f506}|\x{1f507}|\x{1f508}|\x{1f509}|\x{1f50a}|\x{1f50b}|\x{1f50c}|\x{1f50d}|\x{1f50e}|\x{1f50f}|\x{1f510}|\x{1f511}|\x{1f512}|\x{1f513}|\x{1f514}|\x{1f515}|\x{1f516}|\x{1f517}|\x{1f518}|\x{1f519}|\x{1f51a}|\x{1f51b}|\x{1f51c}|\x{1f51d}|\x{1f51e}|\x{1f51f}|\x{1f520}|\x{1f521}|\x{1f522}|\x{1f523}|\x{1f524}|\x{1f525}|\x{1f526}|\x{1f527}|\x{1f528}|\x{1f529}|\x{1f52a}|\x{1f52b}|\x{1f52c}|\x{1f52d}|\x{1f52e}|\x{1f52f}|\x{1f530}|\x{1f531}|\x{1f532}|\x{1f533}|\x{1f534}|\x{1f535}|\x{1f536}|\x{1f537}|\x{1f538}|\x{1f539}|\x{1f53a}|\x{1f53b}|\x{1f53c}|\x{1f53d}|\x{1f54b}|\x{1f54c}|\x{1f54d}|\x{1f54e}|\x{1f550}|\x{1f551}|\x{1f552}|\x{1f553}|\x{1f554}|\x{1f555}|\x{1f556}|\x{1f557}|\x{1f558}|\x{1f559}|\x{1f55a}|\x{1f55b}|\x{1f55c}|\x{1f55d}|\x{1f55e}|\x{1f55f}|\x{1f560}|\x{1f561}|\x{1f562}|\x{1f563}|\x{1f564}|\x{1f565}|\x{1f566}|\x{1f567}|\x{1f5a4}|\x{1f5fb}|\x{1f5fc}|\x{1f5fd}|\x{1f5fe}|\x{1f5ff}|\x{1f600}|\x{1f601}|\x{1f602}|\x{1f603}|\x{1f604}|\x{1f605}|\x{1f606}|\x{1f607}|\x{1f608}|\x{1f609}|\x{1f60a}|\x{1f60b}|\x{1f60c}|\x{1f60d}|\x{1f60e}|\x{1f60f}|\x{1f610}|\x{1f611}|\x{1f612}|\x{1f613}|\x{1f614}|\x{1f615}|\x{1f616}|\x{1f617}|\x{1f618}|\x{1f619}|\x{1f61a}|\x{1f61b}|\x{1f61c}|\x{1f61d}|\x{1f61e}|\x{1f61f}|\x{1f620}|\x{1f621}|\x{1f622}|\x{1f623}|\x{1f624}|\x{1f625}|\x{1f626}|\x{1f627}|\x{1f628}|\x{1f629}|\x{1f62a}|\x{1f62b}|\x{1f62c}|\x{1f62d}|\x{1f62e}|\x{1f62f}|\x{1f630}|\x{1f631}|\x{1f632}|\x{1f633}|\x{1f634}|\x{1f635}|\x{1f636}|\x{1f637}|\x{1f638}|\x{1f639}|\x{1f63a}|\x{1f63b}|\x{1f63c}|\x{1f63d}|\x{1f63e}|\x{1f63f}|\x{1f640}|\x{1f641}|\x{1f642}|\x{1f643}|\x{1f644}|\x{1f648}|\x{1f649}|\x{1f64a}|\x{1f680}|\x{1f681}|\x{1f682}|\x{1f683}|\x{1f684}|\x{1f685}|\x{1f686}|\x{1f687}|\x{1f688}|\x{1f689}|\x{1f68a}|\x{1f68b}|\x{1f68c}|\x{1f68d}|\x{1f68e}|\x{1f68f}|\x{1f690}|\x{1f691}|\x{1f692}|\x{1f693}|\x{1f694}|\x{1f695}|\x{1f696}|\x{1f697}|\x{1f698}|\x{1f699}|\x{1f69a}|\x{1f69b}|\x{1f69c}|\x{1f69d}|\x{1f69e}|\x{1f69f}|\x{1f6a0}|\x{1f6a1}|\x{1f6a2}|\x{1f6a4}|\x{1f6a5}|\x{1f6a6}|\x{1f6a7}|\x{1f6a8}|\x{1f6a9}|\x{1f6aa}|\x{1f6ab}|\x{1f6ac}|\x{1f6ad}|\x{1f6ae}|\x{1f6af}|\x{1f6b0}|\x{1f6b1}|\x{1f6b2}|\x{1f6b3}|\x{1f6b7}|\x{1f6b8}|\x{1f6b9}|\x{1f6ba}|\x{1f6bb}|\x{1f6bc}|\x{1f6bd}|\x{1f6be}|\x{1f6bf}|\x{1f6c1}|\x{1f6c2}|\x{1f6c3}|\x{1f6c4}|\x{1f6c5}|\x{1f6d0}|\x{1f6d1}|\x{1f6d2}|\x{1f6eb}|\x{1f6ec}|\x{1f6f4}|\x{1f6f5}|\x{1f6f6}|\x{1f6f7}|\x{1f6f8}|\x{1f910}|\x{1f911}|\x{1f912}|\x{1f913}|\x{1f914}|\x{1f915}|\x{1f916}|\x{1f917}|\x{1f91d}|\x{1f920}|\x{1f921}|\x{1f922}|\x{1f923}|\x{1f924}|\x{1f925}|\x{1f927}|\x{1f928}|\x{1f929}|\x{1f92a}|\x{1f92b}|\x{1f92c}|\x{1f92d}|\x{1f92e}|\x{1f92f}|\x{1f93a}|\x{1f93c}|\x{1f940}|\x{1f941}|\x{1f942}|\x{1f943}|\x{1f944}|\x{1f945}|\x{1f947}|\x{1f948}|\x{1f949}|\x{1f94a}|\x{1f94b}|\x{1f94c}|\x{1f950}|\x{1f951}|\x{1f952}|\x{1f953}|\x{1f954}|\x{1f955}|\x{1f956}|\x{1f957}|\x{1f958}|\x{1f959}|\x{1f95a}|\x{1f95b}|\x{1f95c}|\x{1f95d}|\x{1f95e}|\x{1f95f}|\x{1f960}|\x{1f961}|\x{1f962}|\x{1f963}|\x{1f964}|\x{1f965}|\x{1f966}|\x{1f967}|\x{1f968}|\x{1f969}|\x{1f96a}|\x{1f96b}|\x{1f980}|\x{1f981}|\x{1f982}|\x{1f983}|\x{1f984}|\x{1f985}|\x{1f986}|\x{1f987}|\x{1f988}|\x{1f989}|\x{1f98a}|\x{1f98b}|\x{1f98c}|\x{1f98d}|\x{1f98e}|\x{1f98f}|\x{1f990}|\x{1f991}|\x{1f992}|\x{1f993}|\x{1f994}|\x{1f995}|\x{1f996}|\x{1f997}|\x{1f9c0}|\x{1f9d0}|\x{1f9de}|\x{1f9df}|\x{1f9e0}|\x{1f9e1}|\x{1f9e2}|\x{1f9e3}|\x{1f9e4}|\x{1f9e5}|\x{1f9e6}|[\x{23e9}\x{23ea}\x{23eb}\x{23ec}\x{23f0}\x{23f3}\x{2640}\x{2642}\x{2695}\x{26ce}\x{2705}\x{2728}\x{274c}\x{274e}\x{2753}\x{2754}\x{2755}\x{2795}\x{2796}\x{2797}\x{27b0}\x{27bf}\x{e50a}]|(?:\x{1f004}|\x{1f170}|\x{1f171}|\x{1f17e}|\x{1f17f}|\x{1f202}|\x{1f21a}|\x{1f22f}|\x{1f237}|\x{1f321}|\x{1f324}|\x{1f325}|\x{1f326}|\x{1f327}|\x{1f328}|\x{1f329}|\x{1f32a}|\x{1f32b}|\x{1f32c}|\x{1f336}|\x{1f37d}|\x{1f396}|\x{1f397}|\x{1f399}|\x{1f39a}|\x{1f39b}|\x{1f39e}|\x{1f39f}|\x{1f3cd}|\x{1f3ce}|\x{1f3d4}|\x{1f3d5}|\x{1f3d6}|\x{1f3d7}|\x{1f3d8}|\x{1f3d9}|\x{1f3da}|\x{1f3db}|\x{1f3dc}|\x{1f3dd}|\x{1f3de}|\x{1f3df}|\x{1f3f3}|\x{1f3f5}|\x{1f3f7}|\x{1f43f}|\x{1f441}|\x{1f4fd}|\x{1f549}|\x{1f54a}|\x{1f56f}|\x{1f570}|\x{1f573}|\x{1f576}|\x{1f577}|\x{1f578}|\x{1f579}|\x{1f587}|\x{1f58a}|\x{1f58b}|\x{1f58c}|\x{1f58d}|\x{1f5a5}|\x{1f5a8}|\x{1f5b1}|\x{1f5b2}|\x{1f5bc}|\x{1f5c2}|\x{1f5c3}|\x{1f5c4}|\x{1f5d1}|\x{1f5d2}|\x{1f5d3}|\x{1f5dc}|\x{1f5dd}|\x{1f5de}|\x{1f5e1}|\x{1f5e3}|\x{1f5e8}|\x{1f5ef}|\x{1f5f3}|\x{1f5fa}|\x{1f6cb}|\x{1f6cd}|\x{1f6ce}|\x{1f6cf}|\x{1f6e0}|\x{1f6e1}|\x{1f6e2}|\x{1f6e3}|\x{1f6e4}|\x{1f6e5}|\x{1f6e9}|\x{1f6f0}|\x{1f6f3}|[\x{00a9}\x{00ae}\x{203c}\x{2049}\x{2122}\x{2139}\x{2194}\x{2195}\x{2196}\x{2197}\x{2198}\x{2199}\x{21a9}\x{21aa}\x{231a}\x{231b}\x{2328}\x{23cf}\x{23ed}\x{23ee}\x{23ef}\x{23f1}\x{23f2}\x{23f8}\x{23f9}\x{23fa}\x{24c2}\x{25aa}\x{25ab}\x{25b6}\x{25c0}\x{25fb}\x{25fc}\x{25fd}\x{25fe}\x{2600}\x{2601}\x{2602}\x{2603}\x{2604}\x{260e}\x{2611}\x{2614}\x{2615}\x{2618}\x{2620}\x{2622}\x{2623}\x{2626}\x{262a}\x{262e}\x{262f}\x{2638}\x{2639}\x{263a}\x{2648}\x{2649}\x{264a}\x{264b}\x{264c}\x{264d}\x{264e}\x{264f}\x{2650}\x{2651}\x{2652}\x{2653}\x{2660}\x{2663}\x{2665}\x{2666}\x{2668}\x{267b}\x{267f}\x{2692}\x{2693}\x{2694}\x{2696}\x{2697}\x{2699}\x{269b}\x{269c}\x{26a0}\x{26a1}\x{26aa}\x{26ab}\x{26b0}\x{26b1}\x{26bd}\x{26be}\x{26c4}\x{26c5}\x{26c8}\x{26cf}\x{26d1}\x{26d3}\x{26d4}\x{26e9}\x{26ea}\x{26f0}\x{26f1}\x{26f2}\x{26f3}\x{26f4}\x{26f5}\x{26f8}\x{26fa}\x{26fd}\x{2702}\x{2708}\x{2709}\x{270f}\x{2712}\x{2714}\x{2716}\x{271d}\x{2721}\x{2733}\x{2734}\x{2744}\x{2747}\x{2757}\x{2763}\x{2764}\x{27a1}\x{2934}\x{2935}\x{2b05}\x{2b06}\x{2b07}\x{2b1b}\x{2b1c}\x{2b50}\x{2b55}\x{3030}\x{303d}\x{3297}\x{3299}])(?:\x{fe0f}|(?!\x{fe0e})))/u'; 
     5312    $entities = '/(&#x1f468;|&#x1f469;(?:&#x1f3fb;|&#x1f3fc;|&#x1f3fd;|&#x1f3fe;|&#x1f3ff;)?&#x200d;(?:&#x2695;&#xfe0f;|&#x2696;&#xfe0f;|&#x2708;&#xfe0f;|&#x1f33e;|&#x1f373;|&#x1f393;|&#x1f3a4;|&#x1f3a8;|&#x1f3eb;|&#x1f3ed;|&#x1f4bb;|&#x1f4bc;|&#x1f527;|&#x1f52c;|&#x1f680;|&#x1f692;)|(?:&#x1f3cb;|&#x1f3cc;|&#x1f575;|&#x26f9;)(?:&#xfe0f;|&#x1f3fb;|&#x1f3fc;|&#x1f3fd;|&#x1f3fe;|&#x1f3ff;)&#x200d;&#x2640;&#xfe0f;|&#x200d;&#x2642;&#xfe0f;|(?:&#x1f3c3;|&#x1f3c4;|&#x1f3ca;|&#x1f46e;|&#x1f471;|&#x1f473;|&#x1f477;|&#x1f481;|&#x1f482;|&#x1f486;|&#x1f487;|&#x1f645;|&#x1f646;|&#x1f647;|&#x1f64b;|&#x1f64d;|&#x1f64e;|&#x1f6a3;|&#x1f6b4;|&#x1f6b5;|&#x1f6b6;|&#x1f926;|&#x1f937;|&#x1f938;|&#x1f939;|&#x1f93d;|&#x1f93e;|&#x1f9d6;|&#x1f9d7;|&#x1f9d8;|&#x1f9d9;|&#x1f9da;|&#x1f9db;|&#x1f9dc;|&#x1f9dd;)(?:&#x1f3fb;|&#x1f3fc;|&#x1f3fd;|&#x1f3fe;|&#x1f3ff;)?&#x200d;&#x2640;&#xfe0f;|&#x200d;&#x2642;&#xfe0f;|&#x1f468;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f48b;&#x200d;&#x1f468;|&#x1f468;&#x200d;&#x1f468;&#x200d;&#x1f466;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f468;&#x200d;&#x1f467;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f468;&#x200d;&#x1f467;&#x200d;&#x1f467;|&#x1f468;&#x200d;&#x1f469;&#x200d;&#x1f466;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f467;|&#x1f469;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f48b;&#x200d;&#x1f468;|&#x1f469;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f48b;&#x200d;&#x1f469;|&#x1f469;&#x200d;&#x1f469;&#x200d;&#x1f466;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f467;|&#x1f468;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f468;|&#x1f468;&#x200d;&#x1f466;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f467;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f467;&#x200d;&#x1f467;|&#x1f468;&#x200d;&#x1f468;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f468;&#x200d;&#x1f467;|&#x1f468;&#x200d;&#x1f469;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f469;&#x200d;&#x1f467;|&#x1f469;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f468;|&#x1f469;&#x200d;&#x2764;&#xfe0f;&#x200d;&#x1f469;|&#x1f469;&#x200d;&#x1f466;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f467;&#x200d;&#x1f467;|&#x1f469;&#x200d;&#x1f469;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f469;&#x200d;&#x1f467;|&#x1f3f3;&#xfe0f;&#x200d;&#x1f308;|&#x1f3f4;&#x200d;&#x2620;&#xfe0f;|&#x1f441;&#x200d;&#x1f5e8;|&#x1f468;&#x200d;&#x1f466;|&#x1f468;&#x200d;&#x1f467;|&#x1f469;&#x200d;&#x1f466;|&#x1f469;&#x200d;&#x1f467;|&#x1f46f;&#x200d;&#x2640;&#xfe0f;|&#x1f46f;&#x200d;&#x2642;&#xfe0f;|&#x1f93c;&#x200d;&#x2640;&#xfe0f;|&#x1f93c;&#x200d;&#x2642;&#xfe0f;|&#x1f9de;&#x200d;&#x2640;&#xfe0f;|&#x1f9de;&#x200d;&#x2642;&#xfe0f;|&#x1f9df;&#x200d;&#x2640;&#xfe0f;|&#x1f9df;&#x200d;&#x2642;&#xfe0f;|(?:(?:&#x0023;|&#x002a;|&#x30;|&#x31;|&#x32;|&#x33;|&#x34;|&#x35;|&#x36;|&#x37;|&#x38;|&#x39;))&#xfe0f;?&#x20e3;|(?:(?:&#x1f3cb;|&#x1f3cc;|&#x1f574;|&#x1f575;|&#x1f590;|(?:&#x261d;|&#x26f7;|&#x26f9;|&#x270c;|&#x270d;))(?:&#xfe0f;|(?!&#xfe0e;))|&#x1f385;|&#x1f3c2;|&#x1f3c3;|&#x1f3c4;|&#x1f3c7;|&#x1f3ca;|&#x1f442;|&#x1f443;|&#x1f446;|&#x1f447;|&#x1f448;|&#x1f449;|&#x1f44a;|&#x1f44b;|&#x1f44c;|&#x1f44d;|&#x1f44e;|&#x1f44f;|&#x1f450;|&#x1f466;|&#x1f467;|&#x1f468;|&#x1f469;|&#x1f46e;|&#x1f470;|&#x1f471;|&#x1f472;|&#x1f473;|&#x1f474;|&#x1f475;|&#x1f476;|&#x1f477;|&#x1f478;|&#x1f47c;|&#x1f481;|&#x1f482;|&#x1f483;|&#x1f485;|&#x1f486;|&#x1f487;|&#x1f4aa;|&#x1f57a;|&#x1f595;|&#x1f596;|&#x1f645;|&#x1f646;|&#x1f647;|&#x1f64b;|&#x1f64c;|&#x1f64d;|&#x1f64e;|&#x1f64f;|&#x1f6a3;|&#x1f6b4;|&#x1f6b5;|&#x1f6b6;|&#x1f6c0;|&#x1f6cc;|&#x1f918;|&#x1f919;|&#x1f91a;|&#x1f91b;|&#x1f91c;|&#x1f91e;|&#x1f91f;|&#x1f926;|&#x1f930;|&#x1f931;|&#x1f932;|&#x1f933;|&#x1f934;|&#x1f935;|&#x1f936;|&#x1f937;|&#x1f938;|&#x1f939;|&#x1f93d;|&#x1f93e;|&#x1f9d1;|&#x1f9d2;|&#x1f9d3;|&#x1f9d4;|&#x1f9d5;|&#x1f9d6;|&#x1f9d7;|&#x1f9d8;|&#x1f9d9;|&#x1f9da;|&#x1f9db;|&#x1f9dc;|&#x1f9dd;|(?:&#x270a;|&#x270b;))(?:&#x1f3fb;|&#x1f3fc;|&#x1f3fd;|&#x1f3fe;|&#x1f3ff;|)|&#x1f3f4;&#xe0067;&#xe0062;&#xe0065;&#xe006e;&#xe0067;&#xe007f;|&#x1f3f4;&#xe0067;&#xe0062;&#xe0073;&#xe0063;&#xe0074;&#xe007f;|&#x1f3f4;&#xe0067;&#xe0062;&#xe0077;&#xe006c;&#xe0073;&#xe007f;|&#x1f1e6;&#x1f1e8;|&#x1f1e6;&#x1f1e9;|&#x1f1e6;&#x1f1ea;|&#x1f1e6;&#x1f1eb;|&#x1f1e6;&#x1f1ec;|&#x1f1e6;&#x1f1ee;|&#x1f1e6;&#x1f1f1;|&#x1f1e6;&#x1f1f2;|&#x1f1e6;&#x1f1f4;|&#x1f1e6;&#x1f1f6;|&#x1f1e6;&#x1f1f7;|&#x1f1e6;&#x1f1f8;|&#x1f1e6;&#x1f1f9;|&#x1f1e6;&#x1f1fa;|&#x1f1e6;&#x1f1fc;|&#x1f1e6;&#x1f1fd;|&#x1f1e6;&#x1f1ff;|&#x1f1e7;&#x1f1e6;|&#x1f1e7;&#x1f1e7;|&#x1f1e7;&#x1f1e9;|&#x1f1e7;&#x1f1ea;|&#x1f1e7;&#x1f1eb;|&#x1f1e7;&#x1f1ec;|&#x1f1e7;&#x1f1ed;|&#x1f1e7;&#x1f1ee;|&#x1f1e7;&#x1f1ef;|&#x1f1e7;&#x1f1f1;|&#x1f1e7;&#x1f1f2;|&#x1f1e7;&#x1f1f3;|&#x1f1e7;&#x1f1f4;|&#x1f1e7;&#x1f1f6;|&#x1f1e7;&#x1f1f7;|&#x1f1e7;&#x1f1f8;|&#x1f1e7;&#x1f1f9;|&#x1f1e7;&#x1f1fb;|&#x1f1e7;&#x1f1fc;|&#x1f1e7;&#x1f1fe;|&#x1f1e7;&#x1f1ff;|&#x1f1e8;&#x1f1e6;|&#x1f1e8;&#x1f1e8;|&#x1f1e8;&#x1f1e9;|&#x1f1e8;&#x1f1eb;|&#x1f1e8;&#x1f1ec;|&#x1f1e8;&#x1f1ed;|&#x1f1e8;&#x1f1ee;|&#x1f1e8;&#x1f1f0;|&#x1f1e8;&#x1f1f1;|&#x1f1e8;&#x1f1f2;|&#x1f1e8;&#x1f1f3;|&#x1f1e8;&#x1f1f4;|&#x1f1e8;&#x1f1f5;|&#x1f1e8;&#x1f1f7;|&#x1f1e8;&#x1f1fa;|&#x1f1e8;&#x1f1fb;|&#x1f1e8;&#x1f1fc;|&#x1f1e8;&#x1f1fd;|&#x1f1e8;&#x1f1fe;|&#x1f1e8;&#x1f1ff;|&#x1f1e9;&#x1f1ea;|&#x1f1e9;&#x1f1ec;|&#x1f1e9;&#x1f1ef;|&#x1f1e9;&#x1f1f0;|&#x1f1e9;&#x1f1f2;|&#x1f1e9;&#x1f1f4;|&#x1f1e9;&#x1f1ff;|&#x1f1ea;&#x1f1e6;|&#x1f1ea;&#x1f1e8;|&#x1f1ea;&#x1f1ea;|&#x1f1ea;&#x1f1ec;|&#x1f1ea;&#x1f1ed;|&#x1f1ea;&#x1f1f7;|&#x1f1ea;&#x1f1f8;|&#x1f1ea;&#x1f1f9;|&#x1f1ea;&#x1f1fa;|&#x1f1eb;&#x1f1ee;|&#x1f1eb;&#x1f1ef;|&#x1f1eb;&#x1f1f0;|&#x1f1eb;&#x1f1f2;|&#x1f1eb;&#x1f1f4;|&#x1f1eb;&#x1f1f7;|&#x1f1ec;&#x1f1e6;|&#x1f1ec;&#x1f1e7;|&#x1f1ec;&#x1f1e9;|&#x1f1ec;&#x1f1ea;|&#x1f1ec;&#x1f1eb;|&#x1f1ec;&#x1f1ec;|&#x1f1ec;&#x1f1ed;|&#x1f1ec;&#x1f1ee;|&#x1f1ec;&#x1f1f1;|&#x1f1ec;&#x1f1f2;|&#x1f1ec;&#x1f1f3;|&#x1f1ec;&#x1f1f5;|&#x1f1ec;&#x1f1f6;|&#x1f1ec;&#x1f1f7;|&#x1f1ec;&#x1f1f8;|&#x1f1ec;&#x1f1f9;|&#x1f1ec;&#x1f1fa;|&#x1f1ec;&#x1f1fc;|&#x1f1ec;&#x1f1fe;|&#x1f1ed;&#x1f1f0;|&#x1f1ed;&#x1f1f2;|&#x1f1ed;&#x1f1f3;|&#x1f1ed;&#x1f1f7;|&#x1f1ed;&#x1f1f9;|&#x1f1ed;&#x1f1fa;|&#x1f1ee;&#x1f1e8;|&#x1f1ee;&#x1f1e9;|&#x1f1ee;&#x1f1ea;|&#x1f1ee;&#x1f1f1;|&#x1f1ee;&#x1f1f2;|&#x1f1ee;&#x1f1f3;|&#x1f1ee;&#x1f1f4;|&#x1f1ee;&#x1f1f6;|&#x1f1ee;&#x1f1f7;|&#x1f1ee;&#x1f1f8;|&#x1f1ee;&#x1f1f9;|&#x1f1ef;&#x1f1ea;|&#x1f1ef;&#x1f1f2;|&#x1f1ef;&#x1f1f4;|&#x1f1ef;&#x1f1f5;|&#x1f1f0;&#x1f1ea;|&#x1f1f0;&#x1f1ec;|&#x1f1f0;&#x1f1ed;|&#x1f1f0;&#x1f1ee;|&#x1f1f0;&#x1f1f2;|&#x1f1f0;&#x1f1f3;|&#x1f1f0;&#x1f1f5;|&#x1f1f0;&#x1f1f7;|&#x1f1f0;&#x1f1fc;|&#x1f1f0;&#x1f1fe;|&#x1f1f0;&#x1f1ff;|&#x1f1f1;&#x1f1e6;|&#x1f1f1;&#x1f1e7;|&#x1f1f1;&#x1f1e8;|&#x1f1f1;&#x1f1ee;|&#x1f1f1;&#x1f1f0;|&#x1f1f1;&#x1f1f7;|&#x1f1f1;&#x1f1f8;|&#x1f1f1;&#x1f1f9;|&#x1f1f1;&#x1f1fa;|&#x1f1f1;&#x1f1fb;|&#x1f1f1;&#x1f1fe;|&#x1f1f2;&#x1f1e6;|&#x1f1f2;&#x1f1e8;|&#x1f1f2;&#x1f1e9;|&#x1f1f2;&#x1f1ea;|&#x1f1f2;&#x1f1eb;|&#x1f1f2;&#x1f1ec;|&#x1f1f2;&#x1f1ed;|&#x1f1f2;&#x1f1f0;|&#x1f1f2;&#x1f1f1;|&#x1f1f2;&#x1f1f2;|&#x1f1f2;&#x1f1f3;|&#x1f1f2;&#x1f1f4;|&#x1f1f2;&#x1f1f5;|&#x1f1f2;&#x1f1f6;|&#x1f1f2;&#x1f1f7;|&#x1f1f2;&#x1f1f8;|&#x1f1f2;&#x1f1f9;|&#x1f1f2;&#x1f1fa;|&#x1f1f2;&#x1f1fb;|&#x1f1f2;&#x1f1fc;|&#x1f1f2;&#x1f1fd;|&#x1f1f2;&#x1f1fe;|&#x1f1f2;&#x1f1ff;|&#x1f1f3;&#x1f1e6;|&#x1f1f3;&#x1f1e8;|&#x1f1f3;&#x1f1ea;|&#x1f1f3;&#x1f1eb;|&#x1f1f3;&#x1f1ec;|&#x1f1f3;&#x1f1ee;|&#x1f1f3;&#x1f1f1;|&#x1f1f3;&#x1f1f4;|&#x1f1f3;&#x1f1f5;|&#x1f1f3;&#x1f1f7;|&#x1f1f3;&#x1f1fa;|&#x1f1f3;&#x1f1ff;|&#x1f1f4;&#x1f1f2;|&#x1f1f5;&#x1f1e6;|&#x1f1f5;&#x1f1ea;|&#x1f1f5;&#x1f1eb;|&#x1f1f5;&#x1f1ec;|&#x1f1f5;&#x1f1ed;|&#x1f1f5;&#x1f1f0;|&#x1f1f5;&#x1f1f1;|&#x1f1f5;&#x1f1f2;|&#x1f1f5;&#x1f1f3;|&#x1f1f5;&#x1f1f7;|&#x1f1f5;&#x1f1f8;|&#x1f1f5;&#x1f1f9;|&#x1f1f5;&#x1f1fc;|&#x1f1f5;&#x1f1fe;|&#x1f1f6;&#x1f1e6;|&#x1f1f7;&#x1f1ea;|&#x1f1f7;&#x1f1f4;|&#x1f1f7;&#x1f1f8;|&#x1f1f7;&#x1f1fa;|&#x1f1f7;&#x1f1fc;|&#x1f1f8;&#x1f1e6;|&#x1f1f8;&#x1f1e7;|&#x1f1f8;&#x1f1e8;|&#x1f1f8;&#x1f1e9;|&#x1f1f8;&#x1f1ea;|&#x1f1f8;&#x1f1ec;|&#x1f1f8;&#x1f1ed;|&#x1f1f8;&#x1f1ee;|&#x1f1f8;&#x1f1ef;|&#x1f1f8;&#x1f1f0;|&#x1f1f8;&#x1f1f1;|&#x1f1f8;&#x1f1f2;|&#x1f1f8;&#x1f1f3;|&#x1f1f8;&#x1f1f4;|&#x1f1f8;&#x1f1f7;|&#x1f1f8;&#x1f1f8;|&#x1f1f8;&#x1f1f9;|&#x1f1f8;&#x1f1fb;|&#x1f1f8;&#x1f1fd;|&#x1f1f8;&#x1f1fe;|&#x1f1f8;&#x1f1ff;|&#x1f1f9;&#x1f1e6;|&#x1f1f9;&#x1f1e8;|&#x1f1f9;&#x1f1e9;|&#x1f1f9;&#x1f1eb;|&#x1f1f9;&#x1f1ec;|&#x1f1f9;&#x1f1ed;|&#x1f1f9;&#x1f1ef;|&#x1f1f9;&#x1f1f0;|&#x1f1f9;&#x1f1f1;|&#x1f1f9;&#x1f1f2;|&#x1f1f9;&#x1f1f3;|&#x1f1f9;&#x1f1f4;|&#x1f1f9;&#x1f1f7;|&#x1f1f9;&#x1f1f9;|&#x1f1f9;&#x1f1fb;|&#x1f1f9;&#x1f1fc;|&#x1f1f9;&#x1f1ff;|&#x1f1fa;&#x1f1e6;|&#x1f1fa;&#x1f1ec;|&#x1f1fa;&#x1f1f2;|&#x1f1fa;&#x1f1f3;|&#x1f1fa;&#x1f1f8;|&#x1f1fa;&#x1f1fe;|&#x1f1fa;&#x1f1ff;|&#x1f1fb;&#x1f1e6;|&#x1f1fb;&#x1f1e8;|&#x1f1fb;&#x1f1ea;|&#x1f1fb;&#x1f1ec;|&#x1f1fb;&#x1f1ee;|&#x1f1fb;&#x1f1f3;|&#x1f1fb;&#x1f1fa;|&#x1f1fc;&#x1f1eb;|&#x1f1fc;&#x1f1f8;|&#x1f1fd;&#x1f1f0;|&#x1f1fe;&#x1f1ea;|&#x1f1fe;&#x1f1f9;|&#x1f1ff;&#x1f1e6;|&#x1f1ff;&#x1f1f2;|&#x1f1ff;&#x1f1fc;|&#x10000;|&#x1f0cf;|&#x1f18e;|&#x1f191;|&#x1f192;|&#x1f193;|&#x1f194;|&#x1f195;|&#x1f196;|&#x1f197;|&#x1f198;|&#x1f199;|&#x1f19a;|&#x1f1e6;|&#x1f1e7;|&#x1f1e8;|&#x1f1e9;|&#x1f1ea;|&#x1f1eb;|&#x1f1ec;|&#x1f1ed;|&#x1f1ee;|&#x1f1ef;|&#x1f1f0;|&#x1f1f1;|&#x1f1f2;|&#x1f1f3;|&#x1f1f4;|&#x1f1f5;|&#x1f1f6;|&#x1f1f7;|&#x1f1f8;|&#x1f1f9;|&#x1f1fa;|&#x1f1fb;|&#x1f1fc;|&#x1f1fd;|&#x1f1fe;|&#x1f1ff;|&#x1f201;|&#x1f232;|&#x1f233;|&#x1f234;|&#x1f235;|&#x1f236;|&#x1f238;|&#x1f239;|&#x1f23a;|&#x1f250;|&#x1f251;|&#x1f300;|&#x1f301;|&#x1f302;|&#x1f303;|&#x1f304;|&#x1f305;|&#x1f306;|&#x1f307;|&#x1f308;|&#x1f309;|&#x1f30a;|&#x1f30b;|&#x1f30c;|&#x1f30d;|&#x1f30e;|&#x1f30f;|&#x1f310;|&#x1f311;|&#x1f312;|&#x1f313;|&#x1f314;|&#x1f315;|&#x1f316;|&#x1f317;|&#x1f318;|&#x1f319;|&#x1f31a;|&#x1f31b;|&#x1f31c;|&#x1f31d;|&#x1f31e;|&#x1f31f;|&#x1f320;|&#x1f32d;|&#x1f32e;|&#x1f32f;|&#x1f330;|&#x1f331;|&#x1f332;|&#x1f333;|&#x1f334;|&#x1f335;|&#x1f337;|&#x1f338;|&#x1f339;|&#x1f33a;|&#x1f33b;|&#x1f33c;|&#x1f33d;|&#x1f33e;|&#x1f33f;|&#x1f340;|&#x1f341;|&#x1f342;|&#x1f343;|&#x1f344;|&#x1f345;|&#x1f346;|&#x1f347;|&#x1f348;|&#x1f349;|&#x1f34a;|&#x1f34b;|&#x1f34c;|&#x1f34d;|&#x1f34e;|&#x1f34f;|&#x1f350;|&#x1f351;|&#x1f352;|&#x1f353;|&#x1f354;|&#x1f355;|&#x1f356;|&#x1f357;|&#x1f358;|&#x1f359;|&#x1f35a;|&#x1f35b;|&#x1f35c;|&#x1f35d;|&#x1f35e;|&#x1f35f;|&#x1f360;|&#x1f361;|&#x1f362;|&#x1f363;|&#x1f364;|&#x1f365;|&#x1f366;|&#x1f367;|&#x1f368;|&#x1f369;|&#x1f36a;|&#x1f36b;|&#x1f36c;|&#x1f36d;|&#x1f36e;|&#x1f36f;|&#x1f370;|&#x1f371;|&#x1f372;|&#x1f373;|&#x1f374;|&#x1f375;|&#x1f376;|&#x1f377;|&#x1f378;|&#x1f379;|&#x1f37a;|&#x1f37b;|&#x1f37c;|&#x1f37e;|&#x1f37f;|&#x1f380;|&#x1f381;|&#x1f382;|&#x1f383;|&#x1f384;|&#x1f386;|&#x1f387;|&#x1f388;|&#x1f389;|&#x1f38a;|&#x1f38b;|&#x1f38c;|&#x1f38d;|&#x1f38e;|&#x1f38f;|&#x1f390;|&#x1f391;|&#x1f392;|&#x1f393;|&#x1f3a0;|&#x1f3a1;|&#x1f3a2;|&#x1f3a3;|&#x1f3a4;|&#x1f3a5;|&#x1f3a6;|&#x1f3a7;|&#x1f3a8;|&#x1f3a9;|&#x1f3aa;|&#x1f3ab;|&#x1f3ac;|&#x1f3ad;|&#x1f3ae;|&#x1f3af;|&#x1f3b0;|&#x1f3b1;|&#x1f3b2;|&#x1f3b3;|&#x1f3b4;|&#x1f3b5;|&#x1f3b6;|&#x1f3b7;|&#x1f3b8;|&#x1f3b9;|&#x1f3ba;|&#x1f3bb;|&#x1f3bc;|&#x1f3bd;|&#x1f3be;|&#x1f3bf;|&#x1f3c0;|&#x1f3c1;|&#x1f3c5;|&#x1f3c6;|&#x1f3c8;|&#x1f3c9;|&#x1f3cf;|&#x1f3d0;|&#x1f3d1;|&#x1f3d2;|&#x1f3d3;|&#x1f3e0;|&#x1f3e1;|&#x1f3e2;|&#x1f3e3;|&#x1f3e4;|&#x1f3e5;|&#x1f3e6;|&#x1f3e7;|&#x1f3e8;|&#x1f3e9;|&#x1f3ea;|&#x1f3eb;|&#x1f3ec;|&#x1f3ed;|&#x1f3ee;|&#x1f3ef;|&#x1f3f0;|&#x1f3f4;|&#x1f3f8;|&#x1f3f9;|&#x1f3fa;|&#x1f3fb;|&#x1f3fc;|&#x1f3fd;|&#x1f3fe;|&#x1f3ff;|&#x1f400;|&#x1f401;|&#x1f402;|&#x1f403;|&#x1f404;|&#x1f405;|&#x1f406;|&#x1f407;|&#x1f408;|&#x1f409;|&#x1f40a;|&#x1f40b;|&#x1f40c;|&#x1f40d;|&#x1f40e;|&#x1f40f;|&#x1f410;|&#x1f411;|&#x1f412;|&#x1f413;|&#x1f414;|&#x1f415;|&#x1f416;|&#x1f417;|&#x1f418;|&#x1f419;|&#x1f41a;|&#x1f41b;|&#x1f41c;|&#x1f41d;|&#x1f41e;|&#x1f41f;|&#x1f420;|&#x1f421;|&#x1f422;|&#x1f423;|&#x1f424;|&#x1f425;|&#x1f426;|&#x1f427;|&#x1f428;|&#x1f429;|&#x1f42a;|&#x1f42b;|&#x1f42c;|&#x1f42d;|&#x1f42e;|&#x1f42f;|&#x1f430;|&#x1f431;|&#x1f432;|&#x1f433;|&#x1f434;|&#x1f435;|&#x1f436;|&#x1f437;|&#x1f438;|&#x1f439;|&#x1f43a;|&#x1f43b;|&#x1f43c;|&#x1f43d;|&#x1f43e;|&#x1f440;|&#x1f444;|&#x1f445;|&#x1f451;|&#x1f452;|&#x1f453;|&#x1f454;|&#x1f455;|&#x1f456;|&#x1f457;|&#x1f458;|&#x1f459;|&#x1f45a;|&#x1f45b;|&#x1f45c;|&#x1f45d;|&#x1f45e;|&#x1f45f;|&#x1f460;|&#x1f461;|&#x1f462;|&#x1f463;|&#x1f464;|&#x1f465;|&#x1f46a;|&#x1f46b;|&#x1f46c;|&#x1f46d;|&#x1f46f;|&#x1f479;|&#x1f47a;|&#x1f47b;|&#x1f47d;|&#x1f47e;|&#x1f47f;|&#x1f480;|&#x1f484;|&#x1f488;|&#x1f489;|&#x1f48a;|&#x1f48b;|&#x1f48c;|&#x1f48d;|&#x1f48e;|&#x1f48f;|&#x1f490;|&#x1f491;|&#x1f492;|&#x1f493;|&#x1f494;|&#x1f495;|&#x1f496;|&#x1f497;|&#x1f498;|&#x1f499;|&#x1f49a;|&#x1f49b;|&#x1f49c;|&#x1f49d;|&#x1f49e;|&#x1f49f;|&#x1f4a0;|&#x1f4a1;|&#x1f4a2;|&#x1f4a3;|&#x1f4a4;|&#x1f4a5;|&#x1f4a6;|&#x1f4a7;|&#x1f4a8;|&#x1f4a9;|&#x1f4ab;|&#x1f4ac;|&#x1f4ad;|&#x1f4ae;|&#x1f4af;|&#x1f4b0;|&#x1f4b1;|&#x1f4b2;|&#x1f4b3;|&#x1f4b4;|&#x1f4b5;|&#x1f4b6;|&#x1f4b7;|&#x1f4b8;|&#x1f4b9;|&#x1f4ba;|&#x1f4bb;|&#x1f4bc;|&#x1f4bd;|&#x1f4be;|&#x1f4bf;|&#x1f4c0;|&#x1f4c1;|&#x1f4c2;|&#x1f4c3;|&#x1f4c4;|&#x1f4c5;|&#x1f4c6;|&#x1f4c7;|&#x1f4c8;|&#x1f4c9;|&#x1f4ca;|&#x1f4cb;|&#x1f4cc;|&#x1f4cd;|&#x1f4ce;|&#x1f4cf;|&#x1f4d0;|&#x1f4d1;|&#x1f4d2;|&#x1f4d3;|&#x1f4d4;|&#x1f4d5;|&#x1f4d6;|&#x1f4d7;|&#x1f4d8;|&#x1f4d9;|&#x1f4da;|&#x1f4db;|&#x1f4dc;|&#x1f4dd;|&#x1f4de;|&#x1f4df;|&#x1f4e0;|&#x1f4e1;|&#x1f4e2;|&#x1f4e3;|&#x1f4e4;|&#x1f4e5;|&#x1f4e6;|&#x1f4e7;|&#x1f4e8;|&#x1f4e9;|&#x1f4ea;|&#x1f4eb;|&#x1f4ec;|&#x1f4ed;|&#x1f4ee;|&#x1f4ef;|&#x1f4f0;|&#x1f4f1;|&#x1f4f2;|&#x1f4f3;|&#x1f4f4;|&#x1f4f5;|&#x1f4f6;|&#x1f4f7;|&#x1f4f8;|&#x1f4f9;|&#x1f4fa;|&#x1f4fb;|&#x1f4fc;|&#x1f4ff;|&#x1f500;|&#x1f501;|&#x1f502;|&#x1f503;|&#x1f504;|&#x1f505;|&#x1f506;|&#x1f507;|&#x1f508;|&#x1f509;|&#x1f50a;|&#x1f50b;|&#x1f50c;|&#x1f50d;|&#x1f50e;|&#x1f50f;|&#x1f510;|&#x1f511;|&#x1f512;|&#x1f513;|&#x1f514;|&#x1f515;|&#x1f516;|&#x1f517;|&#x1f518;|&#x1f519;|&#x1f51a;|&#x1f51b;|&#x1f51c;|&#x1f51d;|&#x1f51e;|&#x1f51f;|&#x1f520;|&#x1f521;|&#x1f522;|&#x1f523;|&#x1f524;|&#x1f525;|&#x1f526;|&#x1f527;|&#x1f528;|&#x1f529;|&#x1f52a;|&#x1f52b;|&#x1f52c;|&#x1f52d;|&#x1f52e;|&#x1f52f;|&#x1f530;|&#x1f531;|&#x1f532;|&#x1f533;|&#x1f534;|&#x1f535;|&#x1f536;|&#x1f537;|&#x1f538;|&#x1f539;|&#x1f53a;|&#x1f53b;|&#x1f53c;|&#x1f53d;|&#x1f54b;|&#x1f54c;|&#x1f54d;|&#x1f54e;|&#x1f550;|&#x1f551;|&#x1f552;|&#x1f553;|&#x1f554;|&#x1f555;|&#x1f556;|&#x1f557;|&#x1f558;|&#x1f559;|&#x1f55a;|&#x1f55b;|&#x1f55c;|&#x1f55d;|&#x1f55e;|&#x1f55f;|&#x1f560;|&#x1f561;|&#x1f562;|&#x1f563;|&#x1f564;|&#x1f565;|&#x1f566;|&#x1f567;|&#x1f5a4;|&#x1f5fb;|&#x1f5fc;|&#x1f5fd;|&#x1f5fe;|&#x1f5ff;|&#x1f600;|&#x1f601;|&#x1f602;|&#x1f603;|&#x1f604;|&#x1f605;|&#x1f606;|&#x1f607;|&#x1f608;|&#x1f609;|&#x1f60a;|&#x1f60b;|&#x1f60c;|&#x1f60d;|&#x1f60e;|&#x1f60f;|&#x1f610;|&#x1f611;|&#x1f612;|&#x1f613;|&#x1f614;|&#x1f615;|&#x1f616;|&#x1f617;|&#x1f618;|&#x1f619;|&#x1f61a;|&#x1f61b;|&#x1f61c;|&#x1f61d;|&#x1f61e;|&#x1f61f;|&#x1f620;|&#x1f621;|&#x1f622;|&#x1f623;|&#x1f624;|&#x1f625;|&#x1f626;|&#x1f627;|&#x1f628;|&#x1f629;|&#x1f62a;|&#x1f62b;|&#x1f62c;|&#x1f62d;|&#x1f62e;|&#x1f62f;|&#x1f630;|&#x1f631;|&#x1f632;|&#x1f633;|&#x1f634;|&#x1f635;|&#x1f636;|&#x1f637;|&#x1f638;|&#x1f639;|&#x1f63a;|&#x1f63b;|&#x1f63c;|&#x1f63d;|&#x1f63e;|&#x1f63f;|&#x1f640;|&#x1f641;|&#x1f642;|&#x1f643;|&#x1f644;|&#x1f648;|&#x1f649;|&#x1f64a;|&#x1f680;|&#x1f681;|&#x1f682;|&#x1f683;|&#x1f684;|&#x1f685;|&#x1f686;|&#x1f687;|&#x1f688;|&#x1f689;|&#x1f68a;|&#x1f68b;|&#x1f68c;|&#x1f68d;|&#x1f68e;|&#x1f68f;|&#x1f690;|&#x1f691;|&#x1f692;|&#x1f693;|&#x1f694;|&#x1f695;|&#x1f696;|&#x1f697;|&#x1f698;|&#x1f699;|&#x1f69a;|&#x1f69b;|&#x1f69c;|&#x1f69d;|&#x1f69e;|&#x1f69f;|&#x1f6a0;|&#x1f6a1;|&#x1f6a2;|&#x1f6a4;|&#x1f6a5;|&#x1f6a6;|&#x1f6a7;|&#x1f6a8;|&#x1f6a9;|&#x1f6aa;|&#x1f6ab;|&#x1f6ac;|&#x1f6ad;|&#x1f6ae;|&#x1f6af;|&#x1f6b0;|&#x1f6b1;|&#x1f6b2;|&#x1f6b3;|&#x1f6b7;|&#x1f6b8;|&#x1f6b9;|&#x1f6ba;|&#x1f6bb;|&#x1f6bc;|&#x1f6bd;|&#x1f6be;|&#x1f6bf;|&#x1f6c1;|&#x1f6c2;|&#x1f6c3;|&#x1f6c4;|&#x1f6c5;|&#x1f6d0;|&#x1f6d1;|&#x1f6d2;|&#x1f6eb;|&#x1f6ec;|&#x1f6f4;|&#x1f6f5;|&#x1f6f6;|&#x1f6f7;|&#x1f6f8;|&#x1f910;|&#x1f911;|&#x1f912;|&#x1f913;|&#x1f914;|&#x1f915;|&#x1f916;|&#x1f917;|&#x1f91d;|&#x1f920;|&#x1f921;|&#x1f922;|&#x1f923;|&#x1f924;|&#x1f925;|&#x1f927;|&#x1f928;|&#x1f929;|&#x1f92a;|&#x1f92b;|&#x1f92c;|&#x1f92d;|&#x1f92e;|&#x1f92f;|&#x1f93a;|&#x1f93c;|&#x1f940;|&#x1f941;|&#x1f942;|&#x1f943;|&#x1f944;|&#x1f945;|&#x1f947;|&#x1f948;|&#x1f949;|&#x1f94a;|&#x1f94b;|&#x1f94c;|&#x1f950;|&#x1f951;|&#x1f952;|&#x1f953;|&#x1f954;|&#x1f955;|&#x1f956;|&#x1f957;|&#x1f958;|&#x1f959;|&#x1f95a;|&#x1f95b;|&#x1f95c;|&#x1f95d;|&#x1f95e;|&#x1f95f;|&#x1f960;|&#x1f961;|&#x1f962;|&#x1f963;|&#x1f964;|&#x1f965;|&#x1f966;|&#x1f967;|&#x1f968;|&#x1f969;|&#x1f96a;|&#x1f96b;|&#x1f980;|&#x1f981;|&#x1f982;|&#x1f983;|&#x1f984;|&#x1f985;|&#x1f986;|&#x1f987;|&#x1f988;|&#x1f989;|&#x1f98a;|&#x1f98b;|&#x1f98c;|&#x1f98d;|&#x1f98e;|&#x1f98f;|&#x1f990;|&#x1f991;|&#x1f992;|&#x1f993;|&#x1f994;|&#x1f995;|&#x1f996;|&#x1f997;|&#x1f9c0;|&#x1f9d0;|&#x1f9de;|&#x1f9df;|&#x1f9e0;|&#x1f9e1;|&#x1f9e2;|&#x1f9e3;|&#x1f9e4;|&#x1f9e5;|&#x1f9e6;|(?:&#x23e9;|&#x23ea;|&#x23eb;|&#x23ec;|&#x23f0;|&#x23f3;|&#x2640;|&#x2642;|&#x2695;|&#x26ce;|&#x2705;|&#x2728;|&#x274c;|&#x274e;|&#x2753;|&#x2754;|&#x2755;|&#x2795;|&#x2796;|&#x2797;|&#x27b0;|&#x27bf;|&#xe50a;)|(?:&#x1f004;|&#x1f170;|&#x1f171;|&#x1f17e;|&#x1f17f;|&#x1f202;|&#x1f21a;|&#x1f22f;|&#x1f237;|&#x1f321;|&#x1f324;|&#x1f325;|&#x1f326;|&#x1f327;|&#x1f328;|&#x1f329;|&#x1f32a;|&#x1f32b;|&#x1f32c;|&#x1f336;|&#x1f37d;|&#x1f396;|&#x1f397;|&#x1f399;|&#x1f39a;|&#x1f39b;|&#x1f39e;|&#x1f39f;|&#x1f3cd;|&#x1f3ce;|&#x1f3d4;|&#x1f3d5;|&#x1f3d6;|&#x1f3d7;|&#x1f3d8;|&#x1f3d9;|&#x1f3da;|&#x1f3db;|&#x1f3dc;|&#x1f3dd;|&#x1f3de;|&#x1f3df;|&#x1f3f3;|&#x1f3f5;|&#x1f3f7;|&#x1f43f;|&#x1f441;|&#x1f4fd;|&#x1f549;|&#x1f54a;|&#x1f56f;|&#x1f570;|&#x1f573;|&#x1f576;|&#x1f577;|&#x1f578;|&#x1f579;|&#x1f587;|&#x1f58a;|&#x1f58b;|&#x1f58c;|&#x1f58d;|&#x1f5a5;|&#x1f5a8;|&#x1f5b1;|&#x1f5b2;|&#x1f5bc;|&#x1f5c2;|&#x1f5c3;|&#x1f5c4;|&#x1f5d1;|&#x1f5d2;|&#x1f5d3;|&#x1f5dc;|&#x1f5dd;|&#x1f5de;|&#x1f5e1;|&#x1f5e3;|&#x1f5e8;|&#x1f5ef;|&#x1f5f3;|&#x1f5fa;|&#x1f6cb;|&#x1f6cd;|&#x1f6ce;|&#x1f6cf;|&#x1f6e0;|&#x1f6e1;|&#x1f6e2;|&#x1f6e3;|&#x1f6e4;|&#x1f6e5;|&#x1f6e9;|&#x1f6f0;|&#x1f6f3;|(?:&#x00a9;|&#x00ae;|&#x203c;|&#x2049;|&#x2122;|&#x2139;|&#x2194;|&#x2195;|&#x2196;|&#x2197;|&#x2198;|&#x2199;|&#x21a9;|&#x21aa;|&#x231a;|&#x231b;|&#x2328;|&#x23cf;|&#x23ed;|&#x23ee;|&#x23ef;|&#x23f1;|&#x23f2;|&#x23f8;|&#x23f9;|&#x23fa;|&#x24c2;|&#x25aa;|&#x25ab;|&#x25b6;|&#x25c0;|&#x25fb;|&#x25fc;|&#x25fd;|&#x25fe;|&#x2600;|&#x2601;|&#x2602;|&#x2603;|&#x2604;|&#x260e;|&#x2611;|&#x2614;|&#x2615;|&#x2618;|&#x2620;|&#x2622;|&#x2623;|&#x2626;|&#x262a;|&#x262e;|&#x262f;|&#x2638;|&#x2639;|&#x263a;|&#x2648;|&#x2649;|&#x264a;|&#x264b;|&#x264c;|&#x264d;|&#x264e;|&#x264f;|&#x2650;|&#x2651;|&#x2652;|&#x2653;|&#x2660;|&#x2663;|&#x2665;|&#x2666;|&#x2668;|&#x267b;|&#x267f;|&#x2692;|&#x2693;|&#x2694;|&#x2696;|&#x2697;|&#x2699;|&#x269b;|&#x269c;|&#x26a0;|&#x26a1;|&#x26aa;|&#x26ab;|&#x26b0;|&#x26b1;|&#x26bd;|&#x26be;|&#x26c4;|&#x26c5;|&#x26c8;|&#x26cf;|&#x26d1;|&#x26d3;|&#x26d4;|&#x26e9;|&#x26ea;|&#x26f0;|&#x26f1;|&#x26f2;|&#x26f3;|&#x26f4;|&#x26f5;|&#x26f8;|&#x26fa;|&#x26fd;|&#x2702;|&#x2708;|&#x2709;|&#x270f;|&#x2712;|&#x2714;|&#x2716;|&#x271d;|&#x2721;|&#x2733;|&#x2734;|&#x2744;|&#x2747;|&#x2757;|&#x2763;|&#x2764;|&#x27a1;|&#x2934;|&#x2935;|&#x2b05;|&#x2b06;|&#x2b07;|&#x2b1b;|&#x2b1c;|&#x2b50;|&#x2b55;|&#x3030;|&#x303d;|&#x3297;|&#x3299;))(?:&#xfe0f;|(?!&#xfe0e;)))/u'; 
     5313    // END: emoji regex 
     5314 
     5315    if ( 'entities' === $type ) { 
     5316        return $entities; 
     5317    } 
     5318 
     5319    return $codepoints; 
     5320} 
     5321 
     5322/** 
    52935323 * Shorten a URL, to be used as link text. 
    52945324 * 
  • trunk/tests/phpunit/tests/formatting/Emoji.php

    r40837 r41043  
    33/** 
    44 * @group formatting 
     5 * @group emoji 
    56 */ 
    67class Tests_Formatting_Emoji extends WP_UnitTestCase { 
     8 
     9    private $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/'; 
     10    private $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/'; 
     11 
    712    /** 
    813     * @ticket 36525 
    914     */ 
    1015    public function test_unfiltered_emoji_cdns() { 
    11         $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/'; 
    12         $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/'; 
    13  
    1416        $output = get_echo( '_print_emoji_detection_script' ); 
    1517 
    16         $this->assertContains( wp_json_encode( $png_cdn ), $output ); 
    17         $this->assertContains( wp_json_encode( $svn_cdn ), $output ); 
     18        $this->assertContains( wp_json_encode( $this->png_cdn ), $output ); 
     19        $this->assertContains( wp_json_encode( $this->svn_cdn ), $output ); 
    1820    } 
    1921 
     
    2628     */ 
    2729    public function test_filtered_emoji_svn_cdn() { 
    28         $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/'; 
    29         $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/'; 
    30  
    3130        $filtered_svn_cdn = $this->_filtered_emoji_svn_cdn(); 
    3231 
     
    3534        $output = get_echo( '_print_emoji_detection_script' ); 
    3635 
    37         $this->assertContains( wp_json_encode( $png_cdn ), $output ); 
    38         $this->assertNotContains( wp_json_encode( $svn_cdn ), $output ); 
     36        $this->assertContains( wp_json_encode( $this->png_cdn ), $output ); 
     37        $this->assertNotContains( wp_json_encode( $this->svn_cdn ), $output ); 
    3938        $this->assertContains( wp_json_encode( $filtered_svn_cdn ), $output ); 
    4039 
     
    5049     */ 
    5150    public function test_filtered_emoji_png_cdn() { 
    52         $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/'; 
    53         $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/'; 
    54  
    5551        $filtered_png_cdn = $this->_filtered_emoji_png_cdn(); 
    5652 
     
    6056 
    6157        $this->assertContains( wp_json_encode( $filtered_png_cdn ), $output ); 
    62         $this->assertNotContains( wp_json_encode( $png_cdn ), $output ); 
    63         $this->assertContains( wp_json_encode( $svn_cdn ), $output ); 
     58        $this->assertNotContains( wp_json_encode( $this->png_cdn ), $output ); 
     59        $this->assertContains( wp_json_encode( $this->svn_cdn ), $output ); 
    6460 
    6561        remove_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) ); 
    6662    } 
    6763 
     64    /** 
     65     * @ticket 35293 
     66     */ 
     67    public function test_wp_emoji_regex_returns_regexen() { 
     68        $default = wp_emoji_regex(); 
     69        $this->assertNotEmpty( $default ); 
     70 
     71        $codepoints = wp_emoji_regex( 'codepoints' ); 
     72        $this->assertNotEmpty( $codepoints ); 
     73 
     74        $this->assertSame( $default, $codepoints ); 
     75 
     76        $entities = wp_emoji_regex( 'entities' ); 
     77        $this->assertNotEmpty( $entities ); 
     78 
     79        $this->assertNotSame( $default, $entities ); 
     80    } 
     81 
     82    public function data_wp_encode_emoji() { 
     83        return array( 
     84            array( 
     85                // Not emoji 
     86                '’', 
     87                '’', 
     88            ), 
     89            array( 
     90                // Simple emoji 
     91                '🙂', 
     92                '&#x1f642;', 
     93            ), 
     94            array( 
     95                // Skin tone, gender, ZWJ, emoji selector 
     96                '👮🏼‍♀️', 
     97                '&#x1f46e;&#x1f3fc;&#x200d;&#x2640;&#xfe0f;', 
     98            ), 
     99            array( 
     100                // Unicode 10 
     101                '🧚', 
     102                '&#x1f9da;', 
     103            ), 
     104 
     105        ); 
     106    } 
     107 
     108    /** 
     109     * @ticket 35293 
     110     * @dataProvider data_wp_encode_emoji 
     111     */ 
     112    public function test_wp_encode_emoji( $emoji, $expected ) { 
     113        $this->assertSame( $expected, wp_encode_emoji( $emoji ) ); 
     114    } 
     115 
     116    public function data_wp_staticize_emoji() { 
     117        return array( 
     118            array( 
     119                // Not emoji 
     120                '’', 
     121                '’', 
     122            ), 
     123            array( 
     124                // Simple emoji 
     125                '🙂', 
     126                '<img src="' . $this->png_cdn . '1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" />', 
     127            ), 
     128            array( 
     129                // Skin tone, gender, ZWJ, emoji selector 
     130                '👮🏼‍♀️', 
     131                '<img src="' . $this->png_cdn . '1f46e-1f3fc-200d-2640-fe0f.png" alt="👮🏼‍♀️" class="wp-smiley" style="height: 1em; max-height: 1em;" />', 
     132            ), 
     133            array( 
     134                // Unicode 10 
     135                '🧚', 
     136                '<img src="' . $this->png_cdn . '1f9da.png" alt="🧚" class="wp-smiley" style="height: 1em; max-height: 1em;" />', 
     137            ), 
     138 
     139        ); 
     140    } 
     141 
     142    /** 
     143     * @ticket 35293 
     144     * @dataProvider data_wp_staticize_emoji 
     145     */ 
     146    public function test_wp_staticize_emoji( $emoji, $expected ) { 
     147        $this->assertSame( $expected, wp_staticize_emoji( $emoji ) ); 
     148    } 
    68149} 
  • trunk/tests/phpunit/tests/formatting/Smilies.php

    r38504 r41043  
    33/** 
    44 * @group formatting 
     5 * @group emoji 
    56 */ 
    67class Tests_Formatting_Smilies extends WP_UnitTestCase { 
Note: See TracChangeset for help on using the changeset viewer.