<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[41069] branches/4.8: Emoji: Port the Twemoji regex to PHP.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/41069">41069</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/41069","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>pento</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-07-18 03:47:29 +0000 (Tue, 18 Jul 2017)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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.

Merges <a href="https://core.trac.wordpress.org/changeset/41043">[41043]</a>, <a href="https://core.trac.wordpress.org/changeset/41045">[41045]</a>, and <a href="https://core.trac.wordpress.org/changeset/41046">[41046]</a> to the 4.8 branch.

Fixes <a href="https://core.trac.wordpress.org/ticket/35293">#35293</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branches48Gruntfilejs">branches/4.8/Gruntfile.js</a></li>
<li><a href="#branches48packagejson">branches/4.8/package.json</a></li>
<li><a href="#branches48srcwpincludesformattingphp">branches/4.8/src/wp-includes/formatting.php</a></li>
<li><a href="#branches48testsphpunittestsformattingEmojiphp">branches/4.8/tests/phpunit/tests/formatting/Emoji.php</a></li>
<li><a href="#branches48testsphpunittestsformattingSmiliesphp">branches/4.8/tests/phpunit/tests/formatting/Smilies.php</a></li>
</ul>

<h3>Property Changed</h3>
<ul>
<li><a href="#branches48">branches/4.8/</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<span class="cx" style="display: block; padding: 0 10px">Index: branches/4.8
</span><span class="cx" style="display: block; padding: 0 10px">===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- branches/4.8 2017-07-18 03:22:34 UTC (rev 41068)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ branches/4.8  2017-07-18 03:47:29 UTC (rev 41069)
</ins><a id="branches48"></a>
<div class="propset"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Property changes: branches/4.8</h4>
<pre class="diff"><span>
</span></pre></div>
<a id="svnmergeinfo"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: svn:mergeinfo</h4></div>
<span class="cx" style="display: block; padding: 0 10px"> /branches/3.1:18031
</span><span class="cx" style="display: block; padding: 0 10px"> /branches/3.3:20543
</span><span class="cx" style="display: block; padding: 0 10px"> /branches/3.4:21757
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/trunk:18512,40872-40873,40879,40881,40883,40885,40892-40893,40896-40897,40901,40926-40927,40939,40941,40990-40991,40995,41000,41009,41020,41022,41028,41035,41037,41047,41050
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/trunk:18512,40872-40873,40879,40881,40883,40885,40892-40893,40896-40897,40901,40926-40927,40939,40941,40990-40991,40995,41000,41009,41020,41022,41028,41035,41037,41043,41045-41047,41050
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="branches48Gruntfilejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/4.8/Gruntfile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/4.8/Gruntfile.js 2017-07-18 03:22:34 UTC (rev 41068)
+++ branches/4.8/Gruntfile.js   2017-07-18 03:47:29 UTC (rev 41069)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -607,6 +607,97 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                dest: '.'
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                replace: {
+                       emojiRegex: {
+                               options: {
+                                       patterns: [
+                                               {
+                                                       match: /\/\/ START: emoji regex[\S\s]*\/\/ END: emoji regex/g,
+                                                       replacement: function () {
+                                                               var twemoji = grunt.file.read( SOURCE_DIR + 'wp-includes/js/twemoji.js' ),
+                                                                       found = twemoji.match( /re = \/(.*)\/g,/ ),
+                                                                       emojiRegex = found[1],
+                                                                       regex = '',
+                                                                       entities = '';
+
+                                                               /*
+                                                                * Twemoji does some nifty regex optimisations, splitting up surrogate pairs unit, searching by
+                                                                * ranges of individual units, and compressing sets of individual units. This is super useful for
+                                                                * reducing the size of the regex.
+                                                                *
+                                                                * Unfortunately, PCRE doesn't allow regexes to search for individual units, so we can't just
+                                                                * blindly copy the Twemoji regex.
+                                                                *
+                                                                * The good news is, we don't have to worry about size restrictions, so we can just unravel the
+                                                                * entire regex, and convert it to a PCRE-friendly format.
+                                                                */
+
+                                                               // Convert ranges: "\udc68-\udc6a" becomes "\udc68\udc69\udc6a".
+                                                               emojiRegex = emojiRegex.replace( /(\\u\w{4})\-(\\u\w{4})/g, function ( match, first, last ) {
+                                                                       var start = parseInt( first.substr( 2 ), 16 );
+                                                                       var end = parseInt( last.substr( 2 ), 16 );
+
+                                                                       var replace = '';
+
+                                                                       for( var counter = start; counter <= end; counter++ ) {
+                                                                               replace += '\\u' + counter.toString( 16 );
+                                                                       }
+
+                                                                       return replace;
+                                                               } );
+
+                                                               // Convert sets: "\u200d[\u2640\u2642]\ufe0f" becomes "\u200d\u2640\ufe0f|\u200d\u2642\ufe0f".
+                                                               emojiRegex = emojiRegex.replace( /((?:\\u\w{4})*)\[((?:\\u\w{4})+)\]((?:\\u\w{4})*)/g, function ( match, before, middle, after ) {
+                                                                       //return params[1].split( '\\u' ).join( '|' + params[0] + '\\u' ).substr( 1 );
+                                                                       if ( ! before && ! after ) {
+                                                                               return match;
+                                                                       }
+                                                                       var set = middle.match( /.{1,6}/g );
+
+                                                                       return before + set.join( after + '|' + before ) + after;
+                                                               } );
+
+                                                               // Convert surrogate pairs to their equivalent unicode scalar: "\ud83d\udc68" becomes "\u1f468".
+                                                               emojiRegex = emojiRegex.replace( /(\\ud[89a-f][0-9a-f]{2})(\\ud[89a-f][0-9a-f]{2})/g, function ( match, first, second ) {
+                                                                       var high = parseInt( first.substr( 2 ), 16 );
+                                                                       var low = parseInt( second.substr( 2 ), 16 );
+
+                                                                       var scalar = ( ( high - 0xD800 ) * 0x400 ) + ( low - 0xDC00 ) + 0x10000;
+
+                                                                       return '\\u' + scalar.toString( 16 );
+                                                               } );
+
+                                                               // Convert JavaScript-style code points to PHP-style: "\u1f468" becomes "\x{1f468}".
+                                                               emojiRegex = emojiRegex.replace( /\\u(\w+)/g, '\\x{$1}' );
+
+                                                               // Convert PHP-style code points to HTML entities: "\x{1f468}" becomes "&#x1f468;".
+                                                               entities = emojiRegex.replace( /\\x{(\w+)}/g, '&#x$1;' );
+                                                               entities = entities.replace( /\[([^\]]+)\]/g, function( match, codepoint ) {
+                                                                       return '(?:' + codepoint.replace( /;&/g, ';|&' ) + ')';
+                                                               } );
+
+                                                               regex += '// START: emoji regex\n';
+                                                               regex += '\t$codepoints = \'/(' + emojiRegex + ')/u\';\n';
+                                                               regex += '\t$entities = \'/(' + entities + ')/u\';\n';
+                                                               regex += '\t// END: emoji regex';
+
+                                                               return regex;
+                                                       }
+                                               }
+                                       ]
+                               },
+                               files: [
+                                       {
+                                               expand: true,
+                                               flatten: true,
+                                               src: [
+                                                       SOURCE_DIR + 'wp-includes/formatting.php'
+                                               ],
+                                               dest: SOURCE_DIR + 'wp-includes/'
+                                       }
+                               ]
+                       }
+               },
</ins><span class="cx" style="display: block; padding: 0 10px">                 _watch: {
</span><span class="cx" style="display: block; padding: 0 10px">                        all: {
</span><span class="cx" style="display: block; padding: 0 10px">                                files: [
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -718,6 +809,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'phpunit'
</span><span class="cx" style="display: block; padding: 0 10px">        ] );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        grunt.registerTask( 'precommit:emoji', [
+               'replace:emojiRegex'
+       ] );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         grunt.registerTask( 'precommit', 'Runs test and build tasks in preparation for a commit', function() {
</span><span class="cx" style="display: block; padding: 0 10px">                var done = this.async();
</span><span class="cx" style="display: block; padding: 0 10px">                var map = {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -783,6 +878,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                        taskList.push( 'precommit:' + extension );
</span><span class="cx" style="display: block; padding: 0 10px">                                                }
</span><span class="cx" style="display: block; padding: 0 10px">                                        } );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                       if ( [ 'twemoji.js' ].some( testPath ) ) {
+                                               grunt.log.writeln( 'twemoji.js has updated. Running `precommit:emoji.' );
+                                               taskList.push( 'precommit:emoji' );
+                                       }
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                grunt.task.run( taskList );
</span></span></pre></div>
<a id="branches48packagejson"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/4.8/package.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/4.8/package.json 2017-07-18 03:22:34 UTC (rev 41068)
+++ branches/4.8/package.json   2017-07-18 03:47:29 UTC (rev 41069)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -30,6 +30,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">     "grunt-legacy-util": "^0.2.0",
</span><span class="cx" style="display: block; padding: 0 10px">     "grunt-patch-wordpress": "~0.4.2",
</span><span class="cx" style="display: block; padding: 0 10px">     "grunt-postcss": "~0.7.1",
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    "grunt-replace": "~1.0.1",
</ins><span class="cx" style="display: block; padding: 0 10px">     "grunt-rtlcss": "~2.0.1",
</span><span class="cx" style="display: block; padding: 0 10px">     "grunt-sass": "~1.2.1",
</span><span class="cx" style="display: block; padding: 0 10px">     "matchdep": "~1.0.0"
</span></span></pre></div>
<a id="branches48srcwpincludesformattingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/4.8/src/wp-includes/formatting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/4.8/src/wp-includes/formatting.php       2017-07-18 03:22:34 UTC (rev 41068)
+++ branches/4.8/src/wp-includes/formatting.php 2017-07-18 03:47:29 UTC (rev 41069)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5084,11 +5084,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Convert any 4 byte emoji in a string to their equivalent HTML entity.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Convert emoji characters to their equivalent HTML entity.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Currently, only Unicode 7 emoji are supported. Skin tone modifiers are allowed,
- * all other Unicode 8 emoji will be added when the spec is finalised.
- *
</del><span class="cx" style="display: block; padding: 0 10px">  * This allows us to store emoji in a DB using the utf8 character set.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.2.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5098,28 +5095,26 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_encode_emoji( $content ) {
</span><span class="cx" style="display: block; padding: 0 10px">        if ( function_exists( 'mb_convert_encoding' ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $regex = '/(
-                    \x23\xE2\x83\xA3               # Digits
-                    [\x30-\x39]\xE2\x83\xA3
-                  | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters
-                  | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
-                  | \xF0\x9F\x98[\x80-\xBF]        # Smilies
-                  | \xF0\x9F\x99[\x80-\x8F]
-                  | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols
-               )/x';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $regex = wp_emoji_regex( 'codepoints' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $matches = array();
</span><span class="cx" style="display: block; padding: 0 10px">                if ( preg_match_all( $regex, $content, $matches ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( ! empty( $matches[1] ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                foreach ( $matches[1] as $emoji ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         foreach ( array_unique( $matches[1] ) as $emoji ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                         /*
</span><span class="cx" style="display: block; padding: 0 10px">                                         * UTF-32's hex encoding is the same as HTML's hex encoding.
</span><span class="cx" style="display: block; padding: 0 10px">                                         * So, by converting the emoji from UTF-8 to UTF-32, we magically
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                         * get the correct hex encoding.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                  * get the correct hex encoding, 0 padded to 8 characters.
</ins><span class="cx" style="display: block; padding: 0 10px">                                          */
</span><span class="cx" style="display: block; padding: 0 10px">                                        $unpacked = unpack( 'H*', mb_convert_encoding( $emoji, 'UTF-32', 'UTF-8' ) );
</span><span class="cx" style="display: block; padding: 0 10px">                                        if ( isset( $unpacked[1] ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                $entity = '&#x' . ltrim( $unpacked[1], '0' ) . ';';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         $parts = str_split( $unpacked[1], 8 );
+                                               $entity = '';
+
+                                               foreach ( $parts as $part ) {
+                                                       $entity .= '&#x' . ltrim( $part, '0' ) . ';';
+                                               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 $content = str_replace( $emoji, $entity, $content );
</span><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5141,12 +5136,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_staticize_emoji( $text ) {
</span><span class="cx" style="display: block; padding: 0 10px">        $text = wp_encode_emoji( $text );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /** This filter is documented in wp-includes/formatting.php */
-       $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.3/72x72/' );
-
-       /** This filter is documented in wp-includes/formatting.php */
-       $ext = apply_filters( 'emoji_ext', '.png' );
-
</del><span class="cx" style="display: block; padding: 0 10px">         $output = '';
</span><span class="cx" style="display: block; padding: 0 10px">        /*
</span><span class="cx" style="display: block; padding: 0 10px">         * HTML loop taken from smiley function, which was taken from texturize function.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5161,6 +5150,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        $tags_to_ignore = 'code|pre|style|script|textarea';
</span><span class="cx" style="display: block; padding: 0 10px">        $ignore_block_element = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $regex = wp_emoji_regex( 'entities' );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         for ( $i = 0; $i < $stop; $i++ ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $content = $textarr[$i];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5171,34 +5162,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // If it's not a tag and not in ignore block.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( '' ==  $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $matches = array();
-                       if ( preg_match_all( '/(&#x1f1(e[6-9a-f]|f[0-9a-f]);){2}/', $content, $matches ) ) {
-                               if ( ! empty( $matches[0] ) ) {
-                                       foreach ( $matches[0] as $flag ) {
-                                               $chars = str_replace( array( '&#x', ';'), '', $flag );
-
-                                               list( $char1, $char2 ) = str_split( $chars, 5 );
-                                               $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 ) );
-
-                                               $content = str_replace( $flag, $entity, $content );
-                                       }
-                               }
-                       }
-
-                       // Loosely match the Emoji Unicode range.
-                       $regex = '/(&#x[2-3][0-9a-f]{3};|&#x1f[1-6][0-9a-f]{2};)/';
-
-                       $matches = array();
-                       if ( preg_match_all( $regex, $content, $matches ) ) {
-                               if ( ! empty( $matches[1] ) ) {
-                                       foreach ( $matches[1] as $emoji ) {
-                                               $char = str_replace( array( '&#x', ';'), '', $emoji );
-                                               $entity = sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="height: 1em; max-height: 1em;" />', $cdn_url . $char . $ext, html_entity_decode( $emoji ) );
-
-                                               $content = str_replace( $emoji, $entity, $content );
-                                       }
-                               }
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $content = preg_replace_callback( $regex, '_wp_staticize_emoji', $content );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Did we exit ignore block.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5213,6 +5177,38 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Callback for wp_staticize_emoji() to turn matched emoji glyphs into images.
+ *
+ * @since 4.8.1
+ * @access private
+ *
+ * @see wp_staticize_emoji()
+ * @staticvar string $cdn_url The CDN url returned by the {@see 'emoji_url'} filter.
+ * @staticvar string $ext     The file extension returned by the {@see 'emoji_ext'} filter.
+ *
+ * @param  array $matches The matched data.
+ * @return string HTML for the static emoji image.
+ */
+function _wp_staticize_emoji( $matches ) {
+       static $cdn_url;
+       if ( ! $cdn_url ) {
+               /** This filter is documented in wp-includes/formatting.php */
+               $cdn_url = apply_filters( 'emoji_url', 'https://s.w.org/images/core/emoji/2.3/72x72/' );
+       }
+
+       static $ext;
+       if ( ! $ext ) {
+               /** This filter is documented in wp-includes/formatting.php */
+               $ext = apply_filters( 'emoji_ext', '.png' );
+       }
+
+       $char = str_replace( ';&#x', '-', $matches[1] );
+       $char = str_replace( array( '&#x', ';'), '', $char );
+
+       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] ) );
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Convert emoji in emails into static images.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.2.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -5280,6 +5276,48 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Returns a regex string to match all emoji that WordPress recognises.
+ *
+ * This regex is automatically built from the regex in twemoji.js - if it needs to be updated,
+ * you should update the regex there, then run the `grunt precommit:emoji` job.
+ *
+ * @since 4.8.1
+ *
+ * @param string $type Optional. Which regex type to return. Accepts 'codepoints' or 'entities', default 'coidepoints'.
+ * @return string A regex to match all emoji that WordPress recognises.
+ */
+function wp_emoji_regex( $type = 'codepoints' ) {
+       // If we're using a PCRE version that doesn't support Unicode, return a loose match regex.
+       if ( 'codepoints' === $type && ( ! defined( 'PCRE_VERSION' ) || version_compare( PCRE_VERSION, '8.32', '<=' ) ) ) {
+               return '/(
+                    \xE2\x99[\x80-\x82]            # Male and female symbols
+                  | [\x23\x30-\x39]\xE2\x83\xA3    # Digits
+                  | \xF0\x9F[\x85-\x88][\xA6-\xBF] # Enclosed characters
+                  | \xF0\x9F[\x8C-\x97][\x80-\xBF] # Misc
+                  | \xF0\x9F\x98[\x80-\xBF]        # Smilies
+                  | \xF0\x9F\x99[\x80-\x8F]
+                  | \xF0\x9F[\xA4-\xA7][\x00-\xFF]
+                  | \xF0\x9F\x9A[\x80-\xBF]        # Transport and map symbols
+                  | \xE2\x80\x8D                   # Zero Width Joiner
+                  | \xEF\xB8\x8F                   # Emoji Variation Selector
+               )/x';
+       }
+
+       // Do not remove the START/END comments - they're used to find where to insert the regex.
+
+       // START: emoji regex
+       $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{20
 0d}\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{27
 0c}\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{1f3
 fd}|\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{1f4
 21}|\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{1f61
 3}|\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{1
 f6b0}|\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{2
 666}\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';
+       $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;|&#x1
 f9d6;|&#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;|&#x1f46
 9;&#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;|&#x1f5
 95;|&#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;&amp
 ;#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;&a
 mp;#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;|&#x1f1f
 5;&#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;|&#x1f
 1f9;&#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;|&#x
 1f1ff;&#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;|&
 amp;#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;|&amp
 ;#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;|&#x
 1f41d;|&#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;|&#x1f4
 88;|&#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;|&a
 mp;#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;|&#x1
 f680;|&#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;|&#x1f6f
 5;|&#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;|&#x1
 f6e1;|&#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';
+       // END: emoji regex
+
+       if ( 'entities' === $type ) {
+               return $entities;
+       }
+
+       return $codepoints;
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Shorten a URL, to be used as link text.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.2.0
</span></span></pre></div>
<a id="branches48testsphpunittestsformattingEmojiphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/4.8/tests/phpunit/tests/formatting/Emoji.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/4.8/tests/phpunit/tests/formatting/Emoji.php     2017-07-18 03:22:34 UTC (rev 41068)
+++ branches/4.8/tests/phpunit/tests/formatting/Emoji.php       2017-07-18 03:47:29 UTC (rev 41069)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,19 +2,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * @group formatting
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @group emoji
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> class Tests_Formatting_Emoji extends WP_UnitTestCase {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       private $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/';
+       private $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/';
+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 36525
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_unfiltered_emoji_cdns() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/';
-               $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/';
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $output = get_echo( '_print_emoji_detection_script' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertContains( wp_json_encode( $png_cdn ), $output );
-               $this->assertContains( wp_json_encode( $svn_cdn ), $output );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertContains( wp_json_encode( $this->png_cdn ), $output );
+               $this->assertContains( wp_json_encode( $this->svn_cdn ), $output );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        public function _filtered_emoji_svn_cdn( $cdn = '' ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -25,17 +27,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 36525
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_filtered_emoji_svn_cdn() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/';
-               $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/';
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $filtered_svn_cdn = $this->_filtered_emoji_svn_cdn();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                add_filter( 'emoji_svg_url', array( $this, '_filtered_emoji_svn_cdn' ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $output = get_echo( '_print_emoji_detection_script' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertContains( wp_json_encode( $png_cdn ), $output );
-               $this->assertNotContains( wp_json_encode( $svn_cdn ), $output );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertContains( wp_json_encode( $this->png_cdn ), $output );
+               $this->assertNotContains( wp_json_encode( $this->svn_cdn ), $output );
</ins><span class="cx" style="display: block; padding: 0 10px">                 $this->assertContains( wp_json_encode( $filtered_svn_cdn ), $output );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                remove_filter( 'emoji_svg_url', array( $this, '_filtered_emoji_svn_cdn' ) );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -49,9 +48,6 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 36525
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_filtered_emoji_png_cdn() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $png_cdn = 'https://s.w.org/images/core/emoji/2.3/72x72/';
-               $svn_cdn = 'https://s.w.org/images/core/emoji/2.3/svg/';
-
</del><span class="cx" style="display: block; padding: 0 10px">                 $filtered_png_cdn = $this->_filtered_emoji_png_cdn();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                add_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -59,10 +55,101 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $output = get_echo( '_print_emoji_detection_script' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertContains( wp_json_encode( $filtered_png_cdn ), $output );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertNotContains( wp_json_encode( $png_cdn ), $output );
-               $this->assertContains( wp_json_encode( $svn_cdn ), $output );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->assertNotContains( wp_json_encode( $this->png_cdn ), $output );
+               $this->assertContains( wp_json_encode( $this->svn_cdn ), $output );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                remove_filter( 'emoji_url', array( $this, '_filtered_emoji_png_cdn' ) );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        /**
+        * @ticket 35293
+        */
+       public function test_wp_emoji_regex_returns_regexen() {
+               $default = wp_emoji_regex();
+               $this->assertNotEmpty( $default );
+
+               $codepoints = wp_emoji_regex( 'codepoints' );
+               $this->assertNotEmpty( $codepoints );
+
+               $this->assertSame( $default, $codepoints );
+
+               $entities = wp_emoji_regex( 'entities' );
+               $this->assertNotEmpty( $entities );
+
+               $this->assertNotSame( $default, $entities );
+       }
+
+       public function data_wp_encode_emoji() {
+               return array(
+                       array(
+                               // Not emoji
+                               '’',
+                               '’',
+                       ),
+                       array(
+                               // Simple emoji
+                               '🙂',
+                               '&#x1f642;',
+                       ),
+                       array(
+                               // Skin tone, gender, ZWJ, emoji selector
+                               '👮🏼‍♀️',
+                               '&#x1f46e;&#x1f3fc;&#x200d;&#x2640;&#xfe0f;',
+                       ),
+                       array(
+                               // Unicode 10
+                               '🧚',
+                               '&#x1f9da;',
+                       ),
+               );
+       }
+
+       /**
+        * @ticket 35293
+        * @dataProvider data_wp_encode_emoji
+        */
+       public function test_wp_encode_emoji( $emoji, $expected ) {
+               $this->assertSame( $expected, wp_encode_emoji( $emoji ) );
+       }
+
+       public function data_wp_staticize_emoji() {
+               $data = array(
+                       array(
+                               // Not emoji
+                               '’',
+                               '’',
+                       ),
+                       array(
+                               // Simple emoji
+                               '🙂',
+                               '<img src="' . $this->png_cdn . '1f642.png" alt="" class="wp-smiley" style="height: 1em; max-height: 1em;" />',
+                       ),
+                       array(
+                               // Skin tone, gender, ZWJ, emoji selector
+                               '👮🏼‍♀️',
+                               '<img src="' . $this->png_cdn . '1f46e-1f3fc-200d-2640-fe0f.png" alt="" class="wp-smiley" style="height: 1em; max-height: 1em;" />',
+                       ),
+                       array(
+                               // Unicode 10
+                               '🧚',
+                               '<img src="' . $this->png_cdn . '1f9da.png" alt="" class="wp-smiley" style="height: 1em; max-height: 1em;" />',
+                       ),
+               );
+
+               // Older versions of PHP don't html_entity_decode() emoji, so we need to make sure they're testing in the expected form.
+               foreach ( $data as $key => $datum ) {
+                       $emoji = html_entity_decode( wp_encode_emoji( $datum[0] ) );
+                       $data[ $key ][1] = str_replace( 'alt=""', 'alt="' . $emoji . '"', $datum[1] );
+               }
+
+               return $data;
+       }
+
+       /**
+        * @ticket 35293
+        * @dataProvider data_wp_staticize_emoji
+        */
+       public function test_wp_staticize_emoji( $emoji, $expected ) {
+               $this->assertSame( $expected, wp_staticize_emoji( $emoji ) );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="branches48testsphpunittestsformattingSmiliesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: branches/4.8/tests/phpunit/tests/formatting/Smilies.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- branches/4.8/tests/phpunit/tests/formatting/Smilies.php   2017-07-18 03:22:34 UTC (rev 41068)
+++ branches/4.8/tests/phpunit/tests/formatting/Smilies.php     2017-07-18 03:47:29 UTC (rev 41069)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,6 +2,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * @group formatting
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @group emoji
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> class Tests_Formatting_Smilies extends WP_UnitTestCase {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre>
</div>
</div>

</body>
</html>