<!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>[10924] sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns: Pattern Directory: Sync with git WordPress/pattern-directory@1c878592553a9dcc8f4f2c8cde05952436fe3f46</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 { white-space: pre-line; 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="http://meta.trac.wordpress.org/changeset/10924">10924</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/10924","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>ryelle</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-04-26 17:12:15 +0000 (Mon, 26 Apr 2021)</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'>Pattern Directory: Sync with git WordPress/pattern-directory@1c878592553a9dcc8f4f2c8cde05952436fe3f46</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsbuildindexassetphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.asset.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsbuildindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorycontextbarscss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-context-bar.scss</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorymenuscss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-menu.scss</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorysearchscss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-search.scss</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_patternscss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_pattern.scss</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscssstylecss">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/style.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsindexphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/index.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssinglewporgpatternphp">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/single-wporg-pattern.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorycontextbarindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorymenudefaultjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/default.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorymenumobilejs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/mobile.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorysearchindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-search/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridmenuindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreactionsjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/actions.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstorereducerjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/reducer.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreresolversjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/resolvers.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreselectorsjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/selectors.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestreducerjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/reducer.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestresolversjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/resolvers.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestselectorsjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/selectors.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreutilsjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/utils.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsimagescopypastedemogif">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/add-to-favorite-button/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentsaddtofavoritebuttonindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/add-to-favorite-button/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorycontextbarmessagingjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/messaging.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/copy-pattern-button/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscopypatternbuttonindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/copy-pattern-button/index.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionscopyguidejs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-guide.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionscopysuccessmessagejs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-success-message.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionsindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/index.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/patterns/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternsindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/patterns/index.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/query-monitor/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentsquerymonitorindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/query-monitor/index.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrchooksindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrchooksroutejs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/route.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestfixturescategoriesjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/fixtures/categories.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilscategoryjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/category.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilsindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/index.js</a></li>
<li>sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/test/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilstestindexjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/test/index.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridmenumessagingjs">sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/messaging.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsbuildindexassetphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.asset.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.asset.php  2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.asset.php    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1 +1 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-data-controls', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-polyfill', 'wp-primitives', 'wp-url', 'wp-viewport'), 'version' => 'eda2ea80abd191600bd93201136beaf6');
</del><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-compose', 'wp-data', 'wp-data-controls', 'wp-element', 'wp-i18n', 'wp-keycodes', 'wp-polyfill', 'wp-primitives', 'wp-url', 'wp-viewport'), 'version' => '47d0699f3951f1009351fbc4a9fef0da');
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsbuildindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.js 2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/build/index.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10595,6 +10595,36 @@
</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">+/***/ "./src/components/add-to-favorite-button/index.js":
+/*!********************************************************!*\
+  !*** ./src/components/add-to-favorite-button/index.js ***!
+  \********************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
+
+
+/**
+ * External dependencies
+ */
+
+
+var AddToFavoriteButton = function AddToFavoriteButton() {
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("button", {
+    className: "button"
+  }, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Add to favorites', 'wporg-patterns'));
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (AddToFavoriteButton);
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/components/category-context-bar/index.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!******************************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/components/category-context-bar/index.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10608,32 +10638,98 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../hooks */ "./src/hooks/index.js");
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../utils */ "./src/utils/index.js");
+/* harmony import */ var _messaging__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./messaging */ "./src/components/category-context-bar/messaging.js");
+/* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../store */ "./src/store/index.js");
</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"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * External dependencies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * WordPress dependencies
</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"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function CategoryContextBar(_ref) {
-  var message = _ref.message,
-      title = _ref.title,
-      links = _ref.links;
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Internal dependencies
+ */
+
+
+
+
+
+
+function CategoryContextBar() {
+  var _useRoute = Object(_hooks__WEBPACK_IMPORTED_MODULE_4__["useRoute"])(),
+      path = _useRoute.path;
+
</ins><span class="cx" style="display: block; padding: 0 10px">   var _useState = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(0),
</span><span class="cx" style="display: block; padding: 0 10px">       _useState2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState, 2),
</span><span class="cx" style="display: block; padding: 0 10px">       height = _useState2[0],
</span><span class="cx" style="display: block; padding: 0 10px">       setHeight = _useState2[1];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var _useState3 = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])({}),
+      _useState4 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState3, 2),
+      context = _useState4[0],
+      setContext = _useState4[1];
+
</ins><span class="cx" style="display: block; padding: 0 10px">   var innerRef = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useRef"])(null);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+  var _useSelect = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useSelect"])(function (select) {
+    var _select = select(_store__WEBPACK_IMPORTED_MODULE_7__["store"]),
+        getCategoryBySlug = _select.getCategoryBySlug,
+        getPatternsByQuery = _select.getPatternsByQuery,
+        isLoadingPatternsByQuery = _select.isLoadingPatternsByQuery,
+        getCurrentQuery = _select.getCurrentQuery;
+
+    var categorySlug = Object(_utils__WEBPACK_IMPORTED_MODULE_5__["getCategoryFromPath"])(path);
+
+    var _category = getCategoryBySlug(categorySlug);
+
+    var query = getCurrentQuery();
+    return {
+      isAllCategory: _category && _category.id === -1,
+      isLoadingPatterns: isLoadingPatternsByQuery(query),
+      patterns: query ? getPatternsByQuery(query) : [],
+      category: _category
+    };
+  }, [path]),
+      isAllCategory = _useSelect.isAllCategory,
+      category = _useSelect.category,
+      isLoadingPatterns = _useSelect.isLoadingPatterns,
+      patterns = _useSelect.patterns;
+
</ins><span class="cx" style="display: block; padding: 0 10px">   Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    if (message) {
-      setHeight(innerRef.current.offsetHeight);
-    } else {
-      setHeight(0);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    if (!category || isLoadingPatterns) {
+      return;
</ins><span class="cx" style="display: block; padding: 0 10px">     }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  }, [message]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+    var searchTerm = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getQueryArg"])(path, 'search');
+    var _context = {}; // Use the category count as default since it has the count of all the associated patterns
+
+    var count = category.count; // If we have a search term use the pattern results length.
+    // Not: This is okay until we start using paging.
+
+    if (searchTerm) {
+      count = patterns.length;
+    }
+
+    if (!isAllCategory || searchTerm) {
+      _context = Object(_messaging__WEBPACK_IMPORTED_MODULE_6__["getContextMessage"])(count, category.name, searchTerm);
+    }
+
+    setContext(_context);
+  }, [category, isLoadingPatterns, patterns]);
+  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
+    var _height = context.message ? innerRef.current.offsetHeight : 0;
+
+    setHeight(_height);
+  }, [context.message]);
</ins><span class="cx" style="display: block; padding: 0 10px">   return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("header", {
</span><span class="cx" style="display: block; padding: 0 10px">     className: "category-context__bar",
</span><span class="cx" style="display: block; padding: 0 10px">     style: {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10643,11 +10739,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">     ref: innerRef
</span><span class="cx" style="display: block; padding: 0 10px">   }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("h2", {
</span><span class="cx" style="display: block; padding: 0 10px">     className: "category-context__bar__copy"
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  }, message), links && links.length > 0 && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  }, context.message), context.links && context.links.length > 0 && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("div", {
</ins><span class="cx" style="display: block; padding: 0 10px">     className: "category-context__bar__links"
</span><span class="cx" style="display: block; padding: 0 10px">   }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("h3", {
</span><span class="cx" style="display: block; padding: 0 10px">     className: "category-context__bar__title"
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  }, title), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("ul", null, links.map(function (i) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  }, context.title), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("ul", null, context.links.map(function (i) {
</ins><span class="cx" style="display: block; padding: 0 10px">     return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("li", {
</span><span class="cx" style="display: block; padding: 0 10px">       key: i.href
</span><span class="cx" style="display: block; padding: 0 10px">     }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("a", {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10660,6 +10756,65 @@
</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">+/***/ "./src/components/category-context-bar/messaging.js":
+/*!**********************************************************!*\
+  !*** ./src/components/category-context-bar/messaging.js ***!
+  \**********************************************************/
+/*! exports provided: getContextMessage */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getContextMessage", function() { return getContextMessage; });
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
+
+
+/**
+ * WordPress dependencies
+ */
+
+
+/**
+ * Returns an object with extra information about the category.
+ *
+ * @param {number} count Number of patterns associated to the category.
+ * @param {string} categoryName The category name.
+ * @param {string|void} searchTerm The search term.
+ * @return {Object}
+ */
+
+var getContextMessage = function getContextMessage(count, categoryName, searchTerm) {
+  var message = Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["sprintf"])(
+  /* translators: %1$d: number of patterns. %2$s category name. */
+  Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["_n"])('%1$d <b>%2$s</b> pattern.', '%1$d <b>%2$s</b> patterns.', count, 'wporg-patterns'), count, categoryName.toLowerCase(), 'wporg-patterns');
+
+  if (searchTerm) {
+    if (categoryName !== 'All') {
+      message = Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["sprintf"])(
+      /* translators: %1$d: number of patterns. %2$s category name. %3$s search term  */
+      Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["_n"])('%1$d <b>%2$s</b> pattern matching "<b>%3$s</b>".', '%1$d <b>%2$s</b> patterns matching "<b>%3$s</b>".', count, 'wporg-patterns'), count, categoryName.toLowerCase(), searchTerm, 'wporg-patterns');
+    } else {
+      message = Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["sprintf"])(
+      /* translators: %1$d: number of patterns. %2$s search term.  */
+      Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["_n"])('%1$d pattern matching "<b>%2$s</b>".', '%1$d patterns matching "<b>%2$s</b>".', count, 'wporg-patterns'), count, searchTerm, 'wporg-patterns');
+    }
+  }
+
+  return {
+    message: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createInterpolateElement"])(message, {
+      b: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("b", null)
+    }),
+    // TODO Fetch these from somewhere
+    title: '',
+    links: []
+  };
+};
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/components/category-menu/default.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!*************************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/components/category-menu/default.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10698,7 +10853,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> var DefaultMenu = function DefaultMenu(_ref2) {
</span><span class="cx" style="display: block; padding: 0 10px">   var path = _ref2.path,
</span><span class="cx" style="display: block; padding: 0 10px">       options = _ref2.options,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-      _onClick = _ref2.onClick,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+      onClick = _ref2.onClick,
</ins><span class="cx" style="display: block; padding: 0 10px">       isLoading = _ref2.isLoading;
</span><span class="cx" style="display: block; padding: 0 10px">   var containerRef = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["useRef"])(null);
</span><span class="cx" style="display: block; padding: 0 10px">   var activeRef = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["useRef"])(null);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10713,7 +10868,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">       width: activeRef.current.offsetWidth,
</span><span class="cx" style="display: block; padding: 0 10px">       height: activeRef.current.offsetHeight
</span><span class="cx" style="display: block; padding: 0 10px">     });
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  }, [containerRef, activeRef, path]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  });
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">   if (!isLoading && !options.length) {
</span><span class="cx" style="display: block; padding: 0 10px">     return null;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10723,16 +10878,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">     className: "category-menu ".concat(isLoading ? 'category-menu--is-loading' : '', " "),
</span><span class="cx" style="display: block; padding: 0 10px">     ref: containerRef
</span><span class="cx" style="display: block; padding: 0 10px">   }, options.map(function (i) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    var isActive = path === i.value;
</ins><span class="cx" style="display: block; padding: 0 10px">     return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("li", {
</span><span class="cx" style="display: block; padding: 0 10px">       key: i.value
</span><span class="cx" style="display: block; padding: 0 10px">     }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("a", {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-      className: path === i.value ? 'category-menu--is-active' : '',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+      className: isActive ? 'category-menu--is-active' : '',
</ins><span class="cx" style="display: block; padding: 0 10px">       href: i.value,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-      ref: path === i.value ? activeRef : null,
-      onClick: function onClick(_ref3) {
-        var target = _ref3.target;
-        return _onClick(target.hash);
-      }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+      ref: isActive ? activeRef : null,
+      onClick: onClick
</ins><span class="cx" style="display: block; padding: 0 10px">     }, i.label));
</span><span class="cx" style="display: block; padding: 0 10px">   }));
</span><span class="cx" style="display: block; padding: 0 10px"> }; // Will only render if the viewport is >= medium
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10823,10 +10976,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">       key: i.value
</span><span class="cx" style="display: block; padding: 0 10px">     }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("a", {
</span><span class="cx" style="display: block; padding: 0 10px">       href: i.value,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-      onClick: function onClick() {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+      onClick: function onClick(event) {
</ins><span class="cx" style="display: block; padding: 0 10px">         setIsOpen(false);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        _onClick(i.value);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        _onClick(event);
</ins><span class="cx" style="display: block; padding: 0 10px">       }
</span><span class="cx" style="display: block; padding: 0 10px">     }, i.label));
</span><span class="cx" style="display: block; padding: 0 10px">   })));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10860,7 +11013,11 @@
</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"> var CategorySearch = function CategorySearch(_ref) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var isLoading = _ref.isLoading;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var defaultValue = _ref.defaultValue,
+      isLoading = _ref.isLoading,
+      isVisible = _ref.isVisible,
+      onUpdate = _ref.onUpdate,
+      onSubmit = _ref.onSubmit;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">   if (isLoading) {
</span><span class="cx" style="display: block; padding: 0 10px">     return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10868,18 +11025,26 @@
</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">+  if (!isVisible) {
+    return null;
+  }
+
</ins><span class="cx" style="display: block; padding: 0 10px">   return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("form", {
</span><span class="cx" style="display: block; padding: 0 10px">     method: "get",
</span><span class="cx" style="display: block; padding: 0 10px">     action: "/",
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    className: "category-search"
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    className: "category-search",
+    onSubmit: onSubmit
</ins><span class="cx" style="display: block; padding: 0 10px">   }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("label", {
</span><span class="cx" style="display: block; padding: 0 10px">     htmlFor: "pattern-search",
</span><span class="cx" style="display: block; padding: 0 10px">     className: "screen-reader-text"
</span><span class="cx" style="display: block; padding: 0 10px">   }, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Search for:', 'wporg-patterns')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("input", {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    onChange: onUpdate,
+    defaultValue: defaultValue,
</ins><span class="cx" style="display: block; padding: 0 10px">     id: "pattern-search",
</span><span class="cx" style="display: block; padding: 0 10px">     type: "search",
</span><span class="cx" style="display: block; padding: 0 10px">     placeholder: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Search patterns', 'wporg-patterns')
</span><span class="cx" style="display: block; padding: 0 10px">   }), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("button", {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    type: "submit",
</ins><span class="cx" style="display: block; padding: 0 10px">     className: "category-search__button"
</span><span class="cx" style="display: block; padding: 0 10px">   }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("span", {
</span><span class="cx" style="display: block; padding: 0 10px">     className: "screen-reader-text"
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10892,6 +11057,78 @@
</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">+/***/ "./src/components/copy-pattern-button/index.js":
+/*!*****************************************************!*\
+  !*** ./src/components/copy-pattern-button/index.js ***!
+  \*****************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
+
+
+/**
+ * External dependencies
+ */
+
+
+/**
+ * Uses a hidden textarea that is added and removed from the DOM in order to copy to clipboard via the Browser.
+ *
+ * @param {string} stringToCopy A string that will be copied to the clipboard
+ * @return {boolean} Whether the copy function succeeded
+ */
+
+var copyToClipboard = function copyToClipboard(stringToCopy) {
+  var element = document.createElement('textarea'); // We don't want the text area to be selected since it's temporary.
+
+  element.setAttribute('readonly', ''); // We don't want the text area to be visible since it's temporary.
+
+  element.style.position = 'absolute';
+  element.style.left = '-9999px';
+  element.value = stringToCopy;
+  document.body.appendChild(element);
+  element.select();
+  var success = document.execCommand('copy');
+  document.body.removeChild(element);
+  return success;
+};
+
+var CopyPatternButton = function CopyPatternButton(_ref) {
+  var onSuccess = _ref.onSuccess;
+
+  var handleClick = function handleClick(_ref2) {
+    var target = _ref2.target;
+    // Grab the pattern markup from hidden input
+    var blockData = document.getElementById('block-data');
+    var blockPattern = JSON.parse(decodeURIComponent(blockData.value));
+    var success = copyToClipboard(blockPattern); // Make sure we reset focus in case it was lost in the 'copy' command.
+
+    target.focus();
+
+    if (success) {
+      onSuccess();
+    } else {// TODO Handle error case
+    }
+  };
+
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__["Button"], {
+    isPrimary: true,
+    onClick: handleClick
+  }, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Copy Pattern', 'wporg-patterns'));
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (CopyPatternButton);
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/components/icons/heart-filled.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!**********************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/components/icons/heart-filled.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11165,30 +11402,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="cx" style="display: block; padding: 0 10px"> __webpack_require__.r(__webpack_exports__);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "../../../../node_modules/@babel/runtime/helpers/slicedToArray.js");
-/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
-/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/core-data */ "@wordpress/core-data");
-/* harmony import */ var _wordpress_core_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
-/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
-/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var _category_menu__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../category-menu */ "./src/components/category-menu/index.js");
-/* harmony import */ var _category_search__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../category-search */ "./src/components/category-search/index.js");
-/* harmony import */ var _category_context_bar__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../category-context-bar */ "./src/components/category-context-bar/index.js");
-/* harmony import */ var _messaging__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./messaging */ "./src/components/pattern-grid-menu/messaging.js");
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_compose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/compose */ "@wordpress/compose");
+/* harmony import */ var _wordpress_compose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_compose__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var _category_menu__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../category-menu */ "./src/components/category-menu/index.js");
+/* harmony import */ var _category_search__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../category-search */ "./src/components/category-search/index.js");
+/* harmony import */ var _category_context_bar__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../category-context-bar */ "./src/components/category-context-bar/index.js");
+/* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../store */ "./src/store/index.js");
+/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../hooks */ "./src/hooks/index.js");
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../utils */ "./src/utils/index.js");
</ins><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">-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * External dependencies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * WordPress dependencies
</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"> 
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11197,73 +11432,71 @@
</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">+
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Module constants
</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">-var PATTERN_TAXONOMY = 'wporg-pattern-category';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+var DEBOUNCE_MS = 300;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> var PatternGridMenu = function PatternGridMenu() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  // Show loading state
-  var _useState = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(true),
-      _useState2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState, 2),
-      showLoading = _useState2[0],
-      setShowLoading = _useState2[1];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var _useRoute = Object(_hooks__WEBPACK_IMPORTED_MODULE_8__["useRoute"])(),
+      path = _useRoute.path,
+      updatePath = _useRoute.update;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var _useState3 = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(false),
-      _useState4 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState3, 2),
-      isFetching = _useState4[0],
-      setIsFetching = _useState4[1];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var _useSelect = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useSelect"])(function (select) {
+    var _select = select(_store__WEBPACK_IMPORTED_MODULE_7__["store"]),
+        getCategories = _select.getCategories,
+        isLoadingCategories = _select.isLoadingCategories,
+        hasLoadedCategories = _select.hasLoadedCategories;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var _useState5 = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(),
-      _useState6 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState5, 2),
-      path = _useState6[0],
-      setPath = _useState6[1];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    return {
+      categories: getCategories(),
+      isLoading: isLoadingCategories(),
+      hasLoaded: hasLoadedCategories()
+    };
+  }),
+      categories = _useSelect.categories,
+      isLoading = _useSelect.isLoading,
+      hasLoaded = _useSelect.hasLoaded;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var _useState7 = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(undefined),
-      _useState8 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState7, 2),
-      categoryContext = _useState8[0],
-      setCategoryContext = _useState8[1];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var handleUpdatePath = function handleUpdatePath(value) {
+    var updatedPath = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["addQueryArgs"])(path, {
+      search: value
+    });
+    updatePath(updatedPath);
+  };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var categories = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_3__["useSelect"])(function (select) {
-    return select(_wordpress_core_data__WEBPACK_IMPORTED_MODULE_2__["store"]).getEntityRecords('taxonomy', PATTERN_TAXONOMY);
-  });
-  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
-    var pathOnLoad = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_4__["getPath"])(window.location.href);
-    setPath(pathOnLoad);
-  }, []);
-  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
-    // Since categories starts as an [] then switches to null
-    if (showLoading && categories === null) {
-      setIsFetching(true);
-    }
-
-    if (isFetching && Array.isArray(categories)) {
-      setShowLoading(false);
-      setIsFetching(false);
-    }
-  }, [isFetching, categories]);
-  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
-    setCategoryContext(_messaging__WEBPACK_IMPORTED_MODULE_8__["default"][path]);
-  }, [path]);
-  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["Fragment"], null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])("nav", {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var debouncedHandleUpdate = Object(_wordpress_compose__WEBPACK_IMPORTED_MODULE_1__["useDebounce"])(handleUpdatePath, DEBOUNCE_MS);
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("nav", {
</ins><span class="cx" style="display: block; padding: 0 10px">     className: "pattern-grid-menu"
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_category_menu__WEBPACK_IMPORTED_MODULE_5__["default"], {
-    path: path,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_category_menu__WEBPACK_IMPORTED_MODULE_4__["default"], {
+    path: Object(_utils__WEBPACK_IMPORTED_MODULE_9__["removeQueryString"])(path),
</ins><span class="cx" style="display: block; padding: 0 10px">     options: categories ? categories.map(function (record) {
</span><span class="cx" style="display: block; padding: 0 10px">       return {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // TODO: This url is temporary and won't use the # symbol
-        value: "#/pattern-categories/".concat(record.slug),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        value: "/".concat(Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getPath"])(record.link) || ''),
</ins><span class="cx" style="display: block; padding: 0 10px">         label: record.name
</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">-    onClick: function onClick(_path) {
-      return setPath(_path);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    onClick: function onClick(event) {
+      event.preventDefault();
+      updatePath(event.target.pathname);
</ins><span class="cx" style="display: block; padding: 0 10px">     },
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    isLoading: showLoading
-  }), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_category_search__WEBPACK_IMPORTED_MODULE_6__["default"], {
-    isLoading: showLoading
-  })), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_category_context_bar__WEBPACK_IMPORTED_MODULE_7__["default"], categoryContext));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    isLoading: isLoading
+  }), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_category_search__WEBPACK_IMPORTED_MODULE_5__["default"], {
+    isLoading: isLoading,
+    isVisible: hasLoaded,
+    defaultValue: Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getQueryArg"])(window.location.href, 'search'),
+    onUpdate: function onUpdate(event) {
+      event.preventDefault();
+      debouncedHandleUpdate(event.target.value);
+    },
+    onSubmit: function onSubmit(event) {
+      event.preventDefault();
+      debouncedHandleUpdate(event.target.elements[0].value);
+    }
+  })), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_category_context_bar__WEBPACK_IMPORTED_MODULE_6__["default"], null));
</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"> /* harmony default export */ __webpack_exports__["default"] = (PatternGridMenu);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11270,45 +11503,6 @@
</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">-/***/ "./src/components/pattern-grid-menu/messaging.js":
-/*!*******************************************************!*\
-  !*** ./src/components/pattern-grid-menu/messaging.js ***!
-  \*******************************************************/
-/*! exports provided: default */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
-/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
-
-/* harmony default export */ __webpack_exports__["default"] = ({
-  '#/pattern-categories/header': {
-    message: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, "45 ", Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("b", null, "Header"), " patterns"),
-    title: 'Related Categories',
-    links: [{
-      href: '/pattern-categories/media',
-      label: 'Media'
-    }, {
-      href: '/pattern-categories/blog',
-      label: 'blog'
-    }]
-  },
-  '#/pattern-categories/footer': {
-    message: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, "23 ", Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("b", null, "Footer"), " patterns that is a very long sentence to check for something."),
-    title: 'Related Categories',
-    links: [{
-      href: '/pattern-categories/media',
-      label: 'Media'
-    }, {
-      href: '/pattern-categories/blog',
-      label: 'blog'
-    }]
-  }
-});
-
-/***/ }),
-
</del><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/components/pattern-grid/index.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!**********************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/components/pattern-grid/index.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11325,8 +11519,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _pattern_thumbnail__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../pattern-thumbnail */ "./src/components/pattern-thumbnail/index.js");
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* harmony import */ var _pattern_grid_menu__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../pattern-grid-menu */ "./src/components/pattern-grid-menu/index.js");
-/* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../store */ "./src/store/index.js");
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../store */ "./src/store/index.js");
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11341,17 +11534,23 @@
</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">-
</del><span class="cx" style="display: block; padding: 0 10px"> function PatternGrid() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var posts = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useSelect"])(function (select) {
-    var _select = select(_store__WEBPACK_IMPORTED_MODULE_5__["store"]),
-        getPatternsByQuery = _select.getPatternsByQuery;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var _useSelect = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useSelect"])(function (select) {
+    var _select = select(_store__WEBPACK_IMPORTED_MODULE_4__["store"]),
+        getPatternsByQuery = _select.getPatternsByQuery,
+        isLoadingPatternsByQuery = _select.isLoadingPatternsByQuery,
+        getCurrentQuery = _select.getCurrentQuery;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    return getPatternsByQuery({});
-  }); // `posts` will be null while the fetch happens.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    var query = getCurrentQuery();
+    return {
+      posts: query ? getPatternsByQuery(query) : [],
+      isLoading: query && isLoadingPatternsByQuery(query)
+    };
+  }),
+      posts = _useSelect.posts,
+      isLoading = _useSelect.isLoading;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var isLoading = !Array.isArray(posts);
-  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_pattern_grid_menu__WEBPACK_IMPORTED_MODULE_4__["default"], null), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
</ins><span class="cx" style="display: block; padding: 0 10px">     className: "pattern-grid"
</span><span class="cx" style="display: block; padding: 0 10px">   }, isLoading ? Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_1__["Spinner"], null) : posts.map(function (post) {
</span><span class="cx" style="display: block; padding: 0 10px">     return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_pattern_thumbnail__WEBPACK_IMPORTED_MODULE_3__["default"], {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11358,7 +11557,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">       key: post.id,
</span><span class="cx" style="display: block; padding: 0 10px">       pattern: post
</span><span class="cx" style="display: block; padding: 0 10px">     });
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  })));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  }));
</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"> /* harmony default export */ __webpack_exports__["default"] = (PatternGrid);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11365,6 +11564,178 @@
</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">+/***/ "./src/components/pattern-preview-actions/copy-guide.js":
+/*!**************************************************************!*\
+  !*** ./src/components/pattern-preview-actions/copy-guide.js ***!
+  \**************************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
+
+
+/**
+ * External dependencies
+ */
+
+
+
+
+var CopyPasteImage = function CopyPasteImage() {
+  return (// Wrap the image to avoid the UI shift after the GIF loads
+    Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
+      style: {
+        height: '220px'
+      }
+    }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("img", {
+      src: "/wp-content/themes/pattern-directory/images/copy-paste-demo.gif",
+      alt: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('GIF of copy and pasting.', 'wporg-patterns')
+    }))
+  );
+};
+
+var CopyGuide = function CopyGuide(_ref) {
+  var onFinish = _ref.onFinish;
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__["Animate"], {
+    type: "appear",
+    options: {
+      origin: 'bottom'
+    }
+  }, function (_ref2) {
+    var className = _ref2.className;
+    return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__["Guide"], {
+      className: "pattern-actions__guide ".concat(className),
+      onFinish: onFinish,
+      finishButtonText: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Close', 'wporg-patterns'),
+      pages: [{
+        image: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(CopyPasteImage, null),
+        content: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", {
+          className: "pattern-actions__guide-content"
+        }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("h3", {
+          className: "pattern-actions__guide-title"
+        }, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('How to use patterns on your WordPress site.', 'wporg-patterns')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("p", null, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Patterns are really just text. And, just like you can copy and paste text, you can copy and paste patterns. Its really easy!', 'wporg-patterns')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("ol", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("li", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("p", null, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Open any post or page in the WordPress block editor.', 'wporg-patterns'))), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createEl
 ement"])("li", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("p", null, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Place your cursor where you want to add the pattern.', 'wporg-patterns'))), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("li", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("p", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createInterpolateElement"])(Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Paste the contents of your clipboard by pressing both the <kbd>⌘</kbd> and <kbd>v</kbd> keys, or right-clicking and choose "Paste" from the menu.', 'wporg-patterns'), {
+          kbd: Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("kbd", {
+            className: "pattern-actions__guide-shortcut"
+          })
+        })))))
+      }]
+    });
+  });
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (CopyGuide);
+
+/***/ }),
+
+/***/ "./src/components/pattern-preview-actions/copy-success-message.js":
+/*!************************************************************************!*\
+  !*** ./src/components/pattern-preview-actions/copy-success-message.js ***!
+  \************************************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/components */ "@wordpress/components");
+/* harmony import */ var _wordpress_components__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__);
+
+
+/**
+ * External dependencies
+ */
+
+
+
+var CopySuccessMessage = function CopySuccessMessage(_ref) {
+  var onClick = _ref.onClick;
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__["Notice"], {
+    className: "pattern-actions__notice",
+    status: "success",
+    isDismissible: false
+  }, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("div", null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])("b", null, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Pattern copied!', 'wporg-patterns')), Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])(' Now you can paste it into any WordPress post or page.', 'wporg-patterns')), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_wordpress_components__WEBPACK_IMPORTED_MODULE_2__["Button"], {
+    onClick: onClick,
+    isSecondary: true
+  }, Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_1__["__"])('Learn More', 'wporg-patterns')));
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (CopySuccessMessage);
+
+/***/ }),
+
+/***/ "./src/components/pattern-preview-actions/index.js":
+/*!*********************************************************!*\
+  !*** ./src/components/pattern-preview-actions/index.js ***!
+  \*********************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "../../../../node_modules/@babel/runtime/helpers/slicedToArray.js");
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _copy_pattern_button__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../copy-pattern-button */ "./src/components/copy-pattern-button/index.js");
+/* harmony import */ var _add_to_favorite_button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../add-to-favorite-button */ "./src/components/add-to-favorite-button/index.js");
+/* harmony import */ var _copy_success_message__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./copy-success-message */ "./src/components/pattern-preview-actions/copy-success-message.js");
+/* harmony import */ var _copy_guide__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./copy-guide */ "./src/components/pattern-preview-actions/copy-guide.js");
+
+
+
+/**
+ * External dependencies
+ */
+
+/**
+ * Internal dependencies
+ */
+
+
+
+
+
+
+var PatternPreviewActions = function PatternPreviewActions() {
+  var _useState = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(false),
+      _useState2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState, 2),
+      showSuccess = _useState2[0],
+      setShowSuccess = _useState2[1];
+
+  var _useState3 = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useState"])(false),
+      _useState4 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_useState3, 2),
+      showGuide = _useState4[0],
+      setShowGuide = _useState4[1];
+
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["Fragment"], null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_copy_pattern_button__WEBPACK_IMPORTED_MODULE_2__["default"], {
+    onSuccess: function onSuccess() {
+      return setShowSuccess(true);
+    }
+  }), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_add_to_favorite_button__WEBPACK_IMPORTED_MODULE_3__["default"], null), showSuccess && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_copy_success_message__WEBPACK_IMPORTED_MODULE_4__["default"], {
+    onClick: function onClick() {
+      return setShowGuide(true);
+    }
+  }), showGuide && Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["createElement"])(_copy_guide__WEBPACK_IMPORTED_MODULE_5__["default"], {
+    onFinish: function onFinish() {
+      return setShowGuide(false);
+    }
+  }));
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (PatternPreviewActions);
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/components/pattern-preview/canvas.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!**************************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/components/pattern-preview/canvas.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11738,6 +12109,254 @@
</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">+/***/ "./src/components/patterns/index.js":
+/*!******************************************!*\
+  !*** ./src/components/patterns/index.js ***!
+  \******************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _pattern_grid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../pattern-grid */ "./src/components/pattern-grid/index.js");
+/* harmony import */ var _pattern_grid_menu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../pattern-grid-menu */ "./src/components/pattern-grid-menu/index.js");
+/* harmony import */ var _query_monitor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../query-monitor */ "./src/components/query-monitor/index.js");
+/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../hooks */ "./src/hooks/index.js");
+
+
+/**
+ * Internal dependencies
+ */
+
+
+
+
+
+var Patterns = function Patterns() {
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_hooks__WEBPACK_IMPORTED_MODULE_4__["RouteProvider"], null, Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_query_monitor__WEBPACK_IMPORTED_MODULE_3__["default"], null), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_pattern_grid_menu__WEBPACK_IMPORTED_MODULE_2__["default"], null), Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_pattern_grid__WEBPACK_IMPORTED_MODULE_1__["default"], null));
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (Patterns);
+
+/***/ }),
+
+/***/ "./src/components/query-monitor/index.js":
+/*!***********************************************!*\
+  !*** ./src/components/query-monitor/index.js ***!
+  \***********************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "../../../../node_modules/@babel/runtime/helpers/defineProperty.js");
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
+/* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var _store__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../store */ "./src/store/index.js");
+/* harmony import */ var _hooks__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../hooks */ "./src/hooks/index.js");
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../utils */ "./src/utils/index.js");
+
+
+function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+/**
+ * WordPress dependencies
+ */
+
+
+
+/**
+ * Internal dependencies
+ */
+
+
+
+
+/**
+ * Listens for changes to the path and reconstructs the query object based on the path
+ */
+
+var QueryMonitor = function QueryMonitor() {
+  var _useRoute = Object(_hooks__WEBPACK_IMPORTED_MODULE_5__["useRoute"])(),
+      path = _useRoute.path;
+
+  var query = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useSelect"])(function (select) {
+    var _select = select(_store__WEBPACK_IMPORTED_MODULE_4__["store"]),
+        getCategoryBySlug = _select.getCategoryBySlug,
+        hasLoadedCategories = _select.hasLoadedCategories; // We need categories loaded before building the query
+
+
+    if (!hasLoadedCategories()) {
+      return;
+    }
+
+    var categorySlug = Object(_utils__WEBPACK_IMPORTED_MODULE_6__["getCategoryFromPath"])(path);
+    var category = getCategoryBySlug(categorySlug); // Default to {} if empty
+
+    var queryStrings = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getQueryArgs"])(path);
+    var _query = queryStrings; // If we have a category and it's not the default category
+
+    if (category && category.id !== -1) {
+      _query = _objectSpread(_objectSpread({}, _query), {}, {
+        'pattern-categories': category.id
+      });
+    }
+
+    return _query;
+  }, [path]);
+
+  var _useDispatch = Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["useDispatch"])(_store__WEBPACK_IMPORTED_MODULE_4__["store"]),
+      setCurrentQuery = _useDispatch.setCurrentQuery;
+
+  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
+    setCurrentQuery(query);
+  }, [query]);
+  return null;
+};
+
+/* harmony default export */ __webpack_exports__["default"] = (QueryMonitor);
+
+/***/ }),
+
+/***/ "./src/hooks/index.js":
+/*!****************************!*\
+  !*** ./src/hooks/index.js ***!
+  \****************************/
+/*! exports provided: RouteProvider, useRoute */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _route__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./route */ "./src/hooks/route.js");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RouteProvider", function() { return _route__WEBPACK_IMPORTED_MODULE_0__["RouteProvider"]; });
+
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "useRoute", function() { return _route__WEBPACK_IMPORTED_MODULE_0__["useRoute"]; });
+
+
+
+/***/ }),
+
+/***/ "./src/hooks/route.js":
+/*!****************************!*\
+  !*** ./src/hooks/route.js ***!
+  \****************************/
+/*! exports provided: RouteProvider, useRoute */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RouteProvider", function() { return RouteProvider; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "useRoute", function() { return useRoute; });
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "../../../../node_modules/@babel/runtime/helpers/defineProperty.js");
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "../../../../node_modules/@babel/runtime/helpers/slicedToArray.js");
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1__);
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
+/* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__);
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
+/* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__);
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils */ "./src/utils/index.js");
+
+
+
+
+function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
+
+/**
+ * WordPress dependencies
+ */
+
+
+/**
+ * Internal dependencies
+ */
+
+
+var StateContext = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__["createContext"])();
+function RouteProvider(_ref) {
+  var children = _ref.children;
+
+  var _useState = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__["useState"])(Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getPathAndQueryString"])(window.location.href)),
+      _useState2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1___default()(_useState, 2),
+      path = _useState2[0],
+      setPath = _useState2[1];
+  /**
+   * Combines query strings from the current path and the new path for arguments with values.
+   *
+   * @param {string} newPath Path including query strings
+   * @return {Object} Query strings as an object
+   */
+
+
+  var mergeQueryStrings = function mergeQueryStrings(newPath) {
+    var currentQueryStrings = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getQueryArgs"])(path);
+    var newQueryStrings = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["getQueryArgs"])(newPath);
+
+    var combined = _objectSpread(_objectSpread({}, currentQueryStrings), newQueryStrings); // remove empty query strings
+
+
+    return Object(_utils__WEBPACK_IMPORTED_MODULE_4__["removeEmptyArgs"])(combined);
+  };
+  /**
+   * Combines the current and new path's query strings and updates the browser's url.
+   *
+   * @param {string} newPath
+   */
+
+
+  var _pushState = function _pushState(newPath) {
+    // Merge the existing and new query strings.
+    var newQueryStrings = mergeQueryStrings(newPath); // Remove the query strings from the path
+
+    var pathOnly = Object(_utils__WEBPACK_IMPORTED_MODULE_4__["removeQueryString"])(newPath); // Rebuild the full path
+
+    var rebuiltPath = Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_3__["addQueryArgs"])(pathOnly, newQueryStrings);
+
+    _replaceState(rebuiltPath);
+  };
+  /**
+   * Calls `window.history.pushState` to update the browser's url.
+   *
+   * @param {string} newPath
+   */
+
+
+  var _replaceState = function _replaceState(newPath) {
+    window.history.pushState('', '', newPath);
+    setPath(newPath);
+  };
+
+  return Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__["createElement"])(StateContext.Provider, {
+    value: {
+      path: path,
+      update: _pushState,
+      replace: _replaceState
+    }
+  }, children);
+}
+function useRoute() {
+  var context = Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_2__["useContext"])(StateContext);
+
+  if (context === undefined) {
+    throw new Error('useRoute must be used within a Provider');
+  }
+
+  return context;
+}
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "./src/index.js":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!**********************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/index.js ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11750,7 +12369,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wordpress/element */ "@wordpress/element");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_element__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _components_pattern_preview__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/pattern-preview */ "./src/components/pattern-preview/index.js");
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* harmony import */ var _components_pattern_grid__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/pattern-grid */ "./src/components/pattern-grid/index.js");
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _components_pattern_preview_actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/pattern-preview-actions */ "./src/components/pattern-preview-actions/index.js");
+/* harmony import */ var _components_patterns__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/patterns */ "./src/components/patterns/index.js");
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11762,6 +12382,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"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">  // Load the preview into any awaiting preview container.
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> var previewContainers = document.querySelectorAll('.pattern-preview__container');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11783,10 +12404,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } // Load the preview into any awaiting preview container.
</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">-var gridContainer = document.getElementById('pattern-grid__container');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+var gridContainer = document.getElementById('patterns__container');
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> if (gridContainer) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["render"])(Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_components_pattern_grid__WEBPACK_IMPORTED_MODULE_2__["default"], null), gridContainer);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["render"])(Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_components_patterns__WEBPACK_IMPORTED_MODULE_3__["default"], null), gridContainer);
+} // Load the pattern preview actions
+
+
+var patternActionsContainer = document.getElementById('pattern-actions');
+
+if (patternActionsContainer) {
+  Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["render"])(Object(_wordpress_element__WEBPACK_IMPORTED_MODULE_0__["createElement"])(_components_pattern_preview_actions__WEBPACK_IMPORTED_MODULE_2__["default"], null), patternActionsContainer);
</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"> /***/ }),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11795,7 +12423,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!******************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/store/actions.js ***!
</span><span class="cx" style="display: block; padding: 0 10px">   \******************************/
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*! exports provided: fetchPatterns, loadPatterns */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*! exports provided: fetchPatterns, loadPatterns, setCurrentQuery, fetchCategories, loadCategories */
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ (function(module, __webpack_exports__, __webpack_require__) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11802,6 +12430,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> __webpack_require__.r(__webpack_exports__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fetchPatterns", function() { return fetchPatterns; });
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadPatterns", function() { return loadPatterns; });
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setCurrentQuery", function() { return setCurrentQuery; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fetchCategories", function() { return fetchCategories; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadCategories", function() { return loadCategories; });
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Get the action object signalling that patterns have been requested.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11831,7 +12462,44 @@
</span><span class="cx" style="display: block; padding: 0 10px">     patterns: patterns
</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">+/**
+ * Get the action object signalling that the current view has been set.
+ *
+ * @param {string} query Query object.
+ * @return {Object} Action object.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function setCurrentQuery(query) {
+  return {
+    type: 'SET_CURRENT_QUERY',
+    query: query
+  };
+}
+/**
+ * Get the action object signalling that categories have been requested.
+ *
+ * @return {Object} Action object.
+ */
+
+function fetchCategories() {
+  return {
+    type: 'FETCH_CATEGORIES'
+  };
+}
+/**
+ * Get the action object signalling that categories have been loaded.
+ *
+ * @param {Array} categories A list of categories.
+ * @return {Object} Action object.
+ */
+
+function loadCategories(categories) {
+  return {
+    type: 'LOAD_CATEGORIES',
+    categories: categories
+  };
+}
+
</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"> /***/ "./src/store/index.js":
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11893,24 +12561,27 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!******************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/store/reducer.js ***!
</span><span class="cx" style="display: block; padding: 0 10px">   \******************************/
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*! exports provided: patterns, default */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*! exports provided: patterns, categories, currentQuery, default */
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ (function(module, __webpack_exports__, __webpack_require__) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="cx" style="display: block; padding: 0 10px"> __webpack_require__.r(__webpack_exports__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "patterns", function() { return patterns; });
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "../../../../node_modules/@babel/runtime/helpers/toConsumableArray.js");
-/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "../../../../node_modules/@babel/runtime/helpers/defineProperty.js");
-/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1__);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "categories", function() { return categories; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "currentQuery", function() { return currentQuery; });
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "../../../../node_modules/@babel/runtime/helpers/defineProperty.js");
+/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/toConsumableArray */ "../../../../node_modules/@babel/runtime/helpers/toConsumableArray.js");
+/* harmony import */ var _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1__);
</ins><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/data */ "@wordpress/data");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_data__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ "./src/store/utils.js");
</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"> 
</span><span class="cx" style="display: block; padding: 0 10px"> function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
</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">  * WordPress dependencies
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11917,6 +12588,11 @@
</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">+ * Internal dependencies
+ */
+
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Reducer to track available patterns.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param {Object} state Current state.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11932,12 +12608,59 @@
</span><span class="cx" style="display: block; padding: 0 10px">     queries: queries(state.queries, action)
</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">+/**
+ * Reducer to track categories.
+ *
+ * @param {Object} state Current state.
+ * @param {Object} action Dispatched action.
+ * @return {Object} Updated state.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function categories() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
+  var action = arguments.length > 1 ? arguments[1] : undefined;
+
+  switch (action.type) {
+    case 'FETCH_CATEGORIES':
+      return null;
+    // Indicates the query is in progress
+
+    case 'LOAD_CATEGORIES':
+      // Sort the categories alphabetically.
+      // See: https://github.com/WordPress/pattern-directory/pull/76#issuecomment-818330872
+      var sorted = (action.categories || []).sort(function (a, b) {
+        return a.name.localeCompare(b.name);
+      });
+      return [Object(_utils__WEBPACK_IMPORTED_MODULE_3__["getAllCategory"])()].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default()(sorted));
+  }
+
+  return state;
+}
+/**
+ * Reducer to track the current query.
+ *
+ * @param {Object} state Current state.
+ * @param {Object} action Dispatched action.
+ * @return {Object} Updated state.
+ */
+
+function currentQuery() {
+  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
+  var action = arguments.length > 1 ? arguments[1] : undefined;
+
+  switch (action.type) {
+    case 'SET_CURRENT_QUERY':
+      return action.query;
+  }
+
+  return state;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> function byId() {
</span><span class="cx" style="display: block; padding: 0 10px">   var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
</span><span class="cx" style="display: block; padding: 0 10px">   var action = arguments.length > 1 ? arguments[1] : undefined;
</span><span class="cx" style="display: block; padding: 0 10px">   var patternsById = (action.patterns || []).reduce(function (acc, cur) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-    return _objectSpread(_objectSpread({}, acc), {}, _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default()({}, cur.id, cur));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+    return _objectSpread(_objectSpread({}, acc), {}, _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()({}, cur.id, cur));
</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">   switch (action.type) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11959,7 +12682,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">   switch (action.type) {
</span><span class="cx" style="display: block; padding: 0 10px">     case 'LOAD_BLOCK_PATTERNS':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-      return _objectSpread(_objectSpread({}, state), {}, _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default()({}, action.query, [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(state[action.query] || []), _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(patternIds))));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+      return _objectSpread(_objectSpread({}, state), {}, _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()({}, action.query, [].concat(_babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default()(state[action.query] || []), _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_1___default()(patternIds))));
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">     default:
</span><span class="cx" style="display: block; padding: 0 10px">       return state;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11967,9 +12690,9 @@
</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"> /* harmony default export */ __webpack_exports__["default"] = (Object(_wordpress_data__WEBPACK_IMPORTED_MODULE_2__["combineReducers"])({
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  patterns: patterns // taxonomy items,
-  // filter query,
-  // favorites,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  patterns: patterns,
+  categories: categories,
+  currentQuery: currentQuery // favorites,
</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"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11979,12 +12702,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!********************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/store/resolvers.js ***!
</span><span class="cx" style="display: block; padding: 0 10px">   \********************************/
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*! exports provided: getPatternsByQuery */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*! exports provided: getPatternsByQuery, getCategories */
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ (function(module, __webpack_exports__, __webpack_require__) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="cx" style="display: block; padding: 0 10px"> __webpack_require__.r(__webpack_exports__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPatternsByQuery", function() { return getPatternsByQuery; });
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCategories", function() { return getCategories; });
</ins><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "@babel/runtime/regenerator");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11995,7 +12719,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils */ "./src/store/utils.js");
</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">-var _marked = /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(getPatternsByQuery);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+var _marked = /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(getPatternsByQuery),
+    _marked2 = /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(getCategories);
</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">  * WordPress dependencies
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12045,7 +12770,43 @@
</span><span class="cx" style="display: block; padding: 0 10px">     }
</span><span class="cx" style="display: block; padding: 0 10px">   }, _marked, null, [[1, 11]]);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function getCategories() {
+  var results;
+  return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function getCategories$(_context2) {
+    while (1) {
+      switch (_context2.prev = _context2.next) {
+        case 0:
+          _context2.prev = 0;
+          _context2.next = 3;
+          return Object(_actions__WEBPACK_IMPORTED_MODULE_3__["fetchCategories"])();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        case 3:
+          _context2.next = 5;
+          return Object(_wordpress_data_controls__WEBPACK_IMPORTED_MODULE_2__["apiFetch"])({
+            path: Object(_wordpress_url__WEBPACK_IMPORTED_MODULE_1__["addQueryArgs"])('/wp/v2/pattern-categories')
+          });
+
+        case 5:
+          results = _context2.sent;
+          _context2.next = 8;
+          return Object(_actions__WEBPACK_IMPORTED_MODULE_3__["loadCategories"])(results);
+
+        case 8:
+          _context2.next = 12;
+          break;
+
+        case 10:
+          _context2.prev = 10;
+          _context2.t0 = _context2["catch"](0);
+
+        case 12:
+        case "end":
+          return _context2.stop();
+      }
+    }
+  }, _marked2, null, [[0, 10]]);
+}
+
</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"> /***/ "./src/store/selectors.js":
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12052,7 +12813,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!********************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/store/selectors.js ***!
</span><span class="cx" style="display: block; padding: 0 10px">   \********************************/
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*! exports provided: isLoadingPatternsByQuery, getPatterns, getPatternsByQuery, getPattern */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*! exports provided: isLoadingPatternsByQuery, getPatterns, getPatternsByQuery, getPattern, getCurrentQuery, isLoadingCategories, hasLoadedCategories, getCategories, getCategoryBySlug */
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ (function(module, __webpack_exports__, __webpack_require__) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12061,7 +12822,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPatterns", function() { return getPatterns; });
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPatternsByQuery", function() { return getPatternsByQuery; });
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPattern", function() { return getPattern; });
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ "./src/store/utils.js");
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCurrentQuery", function() { return getCurrentQuery; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLoadingCategories", function() { return isLoadingCategories; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hasLoadedCategories", function() { return hasLoadedCategories; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCategories", function() { return getCategories; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCategoryBySlug", function() { return getCategoryBySlug; });
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ "../../../../node_modules/@babel/runtime/helpers/slicedToArray.js");
+/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ "./src/store/utils.js");
+
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12076,7 +12846,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"> function isLoadingPatternsByQuery(state, query) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var queryString = Object(_utils__WEBPACK_IMPORTED_MODULE_0__["getQueryString"])(query);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var queryString = Object(_utils__WEBPACK_IMPORTED_MODULE_1__["getQueryString"])(query);
</ins><span class="cx" style="display: block; padding: 0 10px">   return !Array.isArray(state.patterns.queries[queryString]);
</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">@@ -12100,7 +12870,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"> function getPatternsByQuery(state, query) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-  var queryString = Object(_utils__WEBPACK_IMPORTED_MODULE_0__["getQueryString"])(query);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  var queryString = Object(_utils__WEBPACK_IMPORTED_MODULE_1__["getQueryString"])(query);
</ins><span class="cx" style="display: block; padding: 0 10px">   return (state.patterns.queries[queryString] || []).map(function (id) {
</span><span class="cx" style="display: block; padding: 0 10px">     return state.patterns.byId[id];
</span><span class="cx" style="display: block; padding: 0 10px">   });
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12117,7 +12887,73 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function getPattern(state, id) {
</span><span class="cx" style="display: block; padding: 0 10px">   return state.patterns.byId[id] || null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Get the current query.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {Object} The current query.
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function getCurrentQuery(state) {
+  return state.currentQuery;
+}
+/**
+ * Check if there is a pending request for category query.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {boolean} True if an API request is in progress for this query.
+ */
+
+function isLoadingCategories(state) {
+  return state.categories === null;
+}
+/**
+ * Check if the categories have been loaded.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {boolean} True if categories is an array.
+ */
+
+function hasLoadedCategories(state) {
+  return Array.isArray(state.categories);
+}
+/**
+ * Get all loaded categories.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {Array} A list of all categories.
+ */
+
+function getCategories(state) {
+  return state.categories;
+}
+/**
+ * Get category by its slug.
+ *
+ * @param {Object} state Global application state.
+ * @param {string} slug Category slug.
+ *
+ * @return {Array|undefined} The requested category.
+ */
+
+function getCategoryBySlug(state, slug) {
+  if (!hasLoadedCategories(state)) {
+    return;
+  }
+
+  var _state$categories$fil = state.categories.filter(function (i) {
+    return i.slug === slug;
+  }),
+      _state$categories$fil2 = _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_0___default()(_state$categories$fil, 1),
+      cat = _state$categories$fil2[0];
+
+  return cat;
+}
+
</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"> /***/ "./src/store/utils.js":
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12124,16 +12960,19 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*!****************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** ./src/store/utils.js ***!
</span><span class="cx" style="display: block; padding: 0 10px">   \****************************/
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/*! exports provided: getQueryString */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/*! exports provided: getQueryString, getAllCategory */
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ (function(module, __webpack_exports__, __webpack_require__) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> "use strict";
</span><span class="cx" style="display: block; padding: 0 10px"> __webpack_require__.r(__webpack_exports__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getQueryString", function() { return getQueryString; });
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllCategory", function() { return getAllCategory; });
</ins><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ "../../../../node_modules/@babel/runtime/helpers/defineProperty.js");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__);
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @wordpress/url */ "@wordpress/url");
</span><span class="cx" style="display: block; padding: 0 10px"> /* harmony import */ var _wordpress_url__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_wordpress_url__WEBPACK_IMPORTED_MODULE_1__);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @wordpress/i18n */ "@wordpress/i18n");
+/* harmony import */ var _wordpress_i18n__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__);
</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"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12140,6 +12979,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * WordPress dependencies
</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">+
</ins><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Convert a query object into a standardized string.
</span><span class="cx" style="display: block; padding: 0 10px">  * See the `stableKey` generation in `getQueryParts`
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12178,9 +13018,114 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">   return stableKey;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Get the first category used to display all patterns.
+ *
+ * See Schema:
+ * https://developer.wordpress.org/rest-api/reference/categories/
+ *
+ * @return {Object} A category object
+ */
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function getAllCategory() {
+  return {
+    id: -1,
+    slug: '',
+    // Slug matches url
+    name: Object(_wordpress_i18n__WEBPACK_IMPORTED_MODULE_2__["__"])('All', 'wporg-patterns'),
+    link: '/'
+  };
+}
+
</ins><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">+/***/ "./src/utils/category.js":
+/*!*******************************!*\
+  !*** ./src/utils/category.js ***!
+  \*******************************/
+/*! exports provided: removeEmptyArgs, removeQueryString, getCategoryFromPath */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeEmptyArgs", function() { return removeEmptyArgs; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeQueryString", function() { return removeQueryString; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getCategoryFromPath", function() { return getCategoryFromPath; });
+/**
+ * Remove the last '/' from a string if it exists.
+ *
+ * @param {string} str Url or url part
+ * @return {string}
+ */
+var removeTrailingSlash = function removeTrailingSlash(str) {
+  return str.replace(/\/$/, '');
+};
+/**
+ * Removes any empty properties or empty strings.
+ *
+ * @param {Object} obj
+ * @return {Object} Object with keys that are defined and not empty
+ */
+
+
+var removeEmptyArgs = function removeEmptyArgs(obj) {
+  var cleaned = {};
+  Object.keys(obj).forEach(function (key) {
+    var arg = obj[key]; // If it's not undefined or null convert it to string and check that it is not empty.
+    // It's a bit of a "trick" to handle non-strings and strings without checking type explicitly.
+
+    if (arg !== undefined && arg !== null && arg.toString().length > 0) {
+      cleaned[key] = arg;
+    }
+  });
+  return cleaned;
+};
+/**
+ * Splits a string at ? and returns the first part.
+ *
+ * @param {string} path Url or url part
+ * @return {string} Returns string or string before ? character.
+ */
+
+var removeQueryString = function removeQueryString(path) {
+  return path.split('?')[0];
+};
+/**
+ * Retrieves the category from a url path without query string params.
+ *
+ * @param {string} path
+ * @return {string} The category slug.
+ */
+
+var getCategoryFromPath = function getCategoryFromPath(path) {
+  var _path = removeQueryString(path);
+
+  _path = removeTrailingSlash(_path);
+  return _path.substring(_path.lastIndexOf('/') + 1);
+};
+
+/***/ }),
+
+/***/ "./src/utils/index.js":
+/*!****************************!*\
+  !*** ./src/utils/index.js ***!
+  \****************************/
+/*! exports provided: getCategoryFromPath, removeQueryString, removeEmptyArgs */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var _category__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./category */ "./src/utils/category.js");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getCategoryFromPath", function() { return _category__WEBPACK_IMPORTED_MODULE_0__["getCategoryFromPath"]; });
+
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "removeQueryString", function() { return _category__WEBPACK_IMPORTED_MODULE_0__["removeQueryString"]; });
+
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "removeEmptyArgs", function() { return _category__WEBPACK_IMPORTED_MODULE_0__["removeEmptyArgs"]; });
+
+
+
+/***/ }),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> /***/ "@babel/runtime/regenerator":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!*************************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** external "regeneratorRuntime" ***!
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12225,17 +13170,6 @@
</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">-/***/ "@wordpress/core-data":
-/*!**********************************!*\
-  !*** external ["wp","coreData"] ***!
-  \**********************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-(function() { module.exports = window["wp"]["coreData"]; }());
-
-/***/ }),
-
</del><span class="cx" style="display: block; padding: 0 10px"> /***/ "@wordpress/data":
</span><span class="cx" style="display: block; padding: 0 10px"> /*!******************************!*\
</span><span class="cx" style="display: block; padding: 0 10px">   !*** external ["wp","data"] ***!
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorycontextbarscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-context-bar.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-context-bar.scss      2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-context-bar.scss        2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,7 +4,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        border-radius: 2px;
</span><span class="cx" style="display: block; padding: 0 10px">        font-size: 0.8125rem;
</span><span class="cx" style="display: block; padding: 0 10px">        overflow: auto;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        transition: all 50ms ease-out;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ transition: all 100ms ease-out;
+       transition-delay: 100ms;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        > div {
</span><span class="cx" style="display: block; padding: 0 10px">                display: flex;
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorymenuscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-menu.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-menu.scss     2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-menu.scss       2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -6,8 +6,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        background: linear-gradient(180deg, hsla(0, 0%, 100%, 0) 94%, $color__wp-blue 0);
</span><span class="cx" style="display: block; padding: 0 10px">        background-repeat: no-repeat;
</span><span class="cx" style="display: block; padding: 0 10px">        background-size: 0;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        background-position-x: 20px;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ background-position-x: 0;
</ins><span class="cx" style="display: block; padding: 0 10px">         transition: all 75ms ease-out;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        min-height: 45px;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        li {
</span><span class="cx" style="display: block; padding: 0 10px">                display: inline-block;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -80,6 +81,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                width: 80%;
</span><span class="cx" style="display: block; padding: 0 10px">                height: 24px;
</span><span class="cx" style="display: block; padding: 0 10px">                left: 0;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                top: calc(50% - 12px);
</ins><span class="cx" style="display: block; padding: 0 10px">                 transition: none;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_categorysearchscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-search.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-search.scss   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_category-search.scss     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,6 +12,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                border: none;
</span><span class="cx" style="display: block; padding: 0 10px">                box-shadow: none;
</span><span class="cx" style="display: block; padding: 0 10px">                font-size: 0.8125rem;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               &:focus {
+                       outline: $color__wp-blue auto 1px;
+               }
</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">        &__button {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,6 +23,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">                background: transparent;
</span><span class="cx" style="display: block; padding: 0 10px">                border: none;
</span><span class="cx" style="display: block; padding: 0 10px">                color: $color__text-lighter;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               &:active {
+                       background: $color-gray-light-600;
+               }
+
+               &:focus {
+                       outline: $color__wp-blue auto 1px;
+               }
</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">        &--is-loading {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -29,7 +41,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                border-radius: 4px;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                @media only screen and (min-width: $breakpoint-mobile) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        width: 224px;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 width: 224px !important;
+                       min-width: auto !important;
</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">        }
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscsscomponents_patternscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_pattern.scss</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_pattern.scss   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/components/_pattern.scss     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,10 +12,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        .entry-header {
</span><span class="cx" style="display: block; padding: 0 10px">                max-width: $size__site-main;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                padding: 2rem 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         padding: 1.5rem;
</ins><span class="cx" style="display: block; padding: 0 10px">                 margin-left: auto;
</span><span class="cx" style="display: block; padding: 0 10px">                margin-right: auto;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                @media only screen and (min-width: $breakpoint-large) {
+                       padding: 1.5rem 0;
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 .entry-title {
</span><span class="cx" style="display: block; padding: 0 10px">                        margin-top: 0;
</span><span class="cx" style="display: block; padding: 0 10px">                        line-height: 1.2;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -25,6 +29,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        .pattern-actions {
</span><span class="cx" style="display: block; padding: 0 10px">                display: flex;
</span><span class="cx" style="display: block; padding: 0 10px">                align-items: stretch;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                flex-wrap: wrap;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                button + button {
</span><span class="cx" style="display: block; padding: 0 10px">                        margin-left: 2em;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -31,6 +36,62 @@
</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">+        .pattern-actions__notice {
+               margin: 1.5rem 0 0;
+               height: auto;
+               flex-basis: 100%;
+
+               // @wordpress/components/notice wraps content
+               > * {
+                       display: flex;
+                       flex-direction: column; // stack on mobile
+                       justify-content: space-between;
+                       align-items: flex-start;
+                       margin: 0;
+
+                       button {
+                               margin-top: 0.75rem;
+                       }
+
+                       @media only screen and (min-width: $breakpoint-small) {
+                               align-items: center;
+                               flex-direction: row;
+
+                               button {
+                                       margin-top: 0;
+                               }
+                       }
+               }
+       }
+
+       .pattern-actions__guide {
+               max-width: $breakpoint-mobile / 1.25;
+
+               // @wordpress/components/guide overrides
+               height: auto;
+               max-height: none;
+       }
+
+       .pattern-actions__guide-content {
+               padding: 1.5rem;
+               line-height: 1.5;
+       }
+
+       .pattern-actions__guide-title {
+               margin: 0;
+       }
+
+       .pattern-actions__guide-shortcut {
+               background: $color-gray-light-300;
+               box-shadow: 0 0 0 1px $color-gray-light-700;
+               padding: 1px;
+               font-weight: 600;
+               min-width: 20px;
+               display: inline-block;
+               text-align: center;
+               border-radius: 2px;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         .entry-content {
</span><span class="cx" style="display: block; padding: 0 10px">                max-width: $size__site-main;
</span><span class="cx" style="display: block; padding: 0 10px">                margin-left: auto;
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternscssstylecss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/style.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/style.css  2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/css/style.css    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1 +1 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-@charset "UTF-8";[class*=col-]{margin:inherit}.row{display:flex;flex-direction:row;flex-wrap:wrap}@media (max-width:768px){.row{flex-direction:column;flex-wrap:nowrap}}.row.gutters>.row{margin-left:-2%}@media (max-width:768px){.row.gutters>.row{margin-left:0}}.row.gutters>.row>[class*=col-]{margin-left:2%}@media (max-width:768px){.row.gutters>.row>[class*=col-]{margin-left:0}}.row.around{justify-content:space-around}.row.between{justify-content:space-between}.row.auto .col{flex-grow:1}.col-1{width:8.3333333333%}.offset-1{margin-left:8.3333333333%}.col-2{width:16.6666666667%}.offset-2{margin-left:16.6666666667%}.col-3{width:25%}.offset-3{margin-left:25%}.col-4{width:33.3333333333%}.offset-4{margin-left:33.3333333333%}.col-5{width:41.6666666667%}.offset-5{margin-left:41.6666666667%}.col-6{width:50%}.offset-6{margin-left:50%}.col-7{width:58.3333333333%}.offset-7{
 margin-left:58.3333333333%}.col-8{width:66.6666666667%}.offset-8{margin-left:66.6666666667%}.col-9{width:75%}.offset-9{margin-left:75%}.col-10{width:83.3333333333%}.offset-10{margin-left:83.3333333333%}.col-11{width:91.6666666667%}.offset-11{margin-left:91.6666666667%}.col-12{width:100%}.offset-12{margin-left:100%}.gutters>.col-1{width:6.33333%}.gutters>.col-1:nth-child(n+13){margin-top:2%}.gutters>.offset-1{margin-left:10.33333%!important}.gutters>.col-2{width:14.66667%}.gutters>.col-2:nth-child(n+7){margin-top:2%}.gutters>.offset-2{margin-left:18.66667%!important}.gutters>.col-3{width:23%}.gutters>.col-3:nth-child(n+5){margin-top:2%}.gutters>.offset-3{margin-left:27%!important}.gutters>.col-4{width:31.33333%}.gutters>.col-4:nth-child(n+4){margin-top:2%}.gutters>.offset-4{margin-left:35.33333%!important}.gutters>.col-5{width:39.66667%}.gutters>.offset-5{margin-left:43.66667%!important}.gutters>.col-6{width:48%}.gutters>.col-6:nth-chil
 d(n+3){margin-top:2%}.gutters>.offset-6{margin-left:52%!important}.gutters>.col-7{width:56.33333%}.gutters>.offset-7{margin-left:60.33333%!important}.gutters>.col-8{width:64.66667%}.gutters>.offset-8{margin-left:68.66667%!important}.gutters>.col-9{width:73%}.gutters>.offset-9{margin-left:77%!important}.gutters>.col-10{width:81.33333%}.gutters>.offset-10{margin-left:85.33333%!important}.gutters>.col-11{width:89.66667%}.gutters>.offset-11{margin-left:93.66667%!important}.gutters>.col-12{width:98%}.gutters>.offset-12{margin-left:102%!important}@media (max-width:768px){[class*=" offset-"],[class^=offset-]{margin-left:0}}.first{order:-1}.last{order:1}@media (max-width:768px){.row [class*=col-]{margin-left:0;width:100%}.row.gutters [class*=col-]{margin-bottom:16px}.first-sm{order:-1}.last-sm{order:1}}.gutters .column.push-left,.push-left{margin-right:auto}.gutters .column.push-right,.push-right{margin-left:auto}.gutters .column.push-center,
 .push-center{margin-left:auto;margin-right:auto}.gutters .column.push-middle,.push-middle{margin-top:auto;margin-bottom:auto}.push-bottom{margin-top:auto}@media (max-width:768px){.gutters .column.push-left-sm,.push-left-sm{margin-left:0}.gutters .column.push-center-sm,.push-center-sm{margin-left:auto;margin-right:auto}.push-top-sm{margin-top:0}}.align-middle{align-items:center}.align-right{justify-content:flex-end}.align-center{justify-content:center}@media (max-width:768px){.align-left-sm{justify-content:flex-start}}.float-right{float:right}.float-left{float:left}@media (max-width:768px){.float-left,.float-right{float:none}}.fixed{position:fixed;top:0;left:0;z-index:100;width:100%}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;he
 ight:0}[hidden],template{display:none}a{background-color:transparent}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webki
 t-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}optgroup{font-weight:700}table{border-spacing:0}td,th{padding:0}p{margin:1rem 0}cite,dfn,em,i{font-style:italic}blockquote{margin:0 1.5rem}address{margin:0 0 1.5rem}pre{background:#eee;font-family:Courier\ 10 Pitch,Courier,monospace;font-size:.9375rem;line-height:1.6;margin-bottom:1.6rem;max-width:100%;overflow:auto;padding:1.6rem}code,kbd,tt,var{font-family:Monaco,Consolas,Andale Mono,DejaVu Sans Mono,monospace;font-size:.9375rem}abbr,acronym{border-bottom:1px dotted #666;cursor:help}ins,mark{background:#fff9c0;text-decoration:none}big{font-size:125%}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{background:#fff}blockquote,q{quotes:"" ""}blockquote:af
 ter,blockquote:before,q:after,q:before{content:""}blockquote{border-left:2px solid #767676;color:#767676;margin:1rem 0;padding-left:.8rem}blockquote cite{font-size:.8rem}figure{margin:0}hr{background-color:#eee;border:0;height:2px;margin:5rem auto}img{height:auto;max-width:100%}h1,h2,h3,h4,h5,h6{font-family:Open Sans,sans-serif;clear:both;line-height:1.5;margin:2rem 0 1rem}.h1,h1{font-size:2.44140625rem}.h1,.h2,h1,h2{font-weight:300}.h2,h2{font-size:1.953125rem}.h3,h3{font-size:1.5625rem;font-weight:400}.h4,h4{font-size:1.25rem;color:#32373c;font-weight:600;padding:0}.h5,h5{font-size:1rem;letter-spacing:.01rem}.h5,.h6,h5,h6{font-weight:600;text-transform:uppercase}.h6,h6{font-size:.8rem;letter-spacing:.8px}a{color:#0073aa;text-decoration:none}a:active,a:focus,a:hover{text-decoration:underline}a:focus{outline:thin dotted}a:active,a:hover{outline:0}li>a,p a{text-decoration:underline}li>a:hover,p a:hover{color:#d54e21}ol,ul{margin:0 0 1.5em 1.5em;padding:0}ul{list-style
 :square}ol{list-style:decimal}ol.unmarked-list,ul.unmarked-list{list-style:none;padding-left:0}li>ol,li>ul{margin-bottom:0}dt{font-weight:700}dd{margin:0 1.5em 1.5em}table{border:1px solid #eee;border-collapse:collapse;font-size:.8rem;margin:0 0 1rem;padding:0;width:100%}table thead{background:#32373c;color:#fff}table td,table th{border:1px solid #eee;font-weight:400;margin:0;padding:.4rem;text-align:left;vertical-align:top}table tbody tr:nth-child(2n){background:#f7f7f7}html{font-size:100%}body,button,input,select,textarea{color:#32373c;font-family:Open Sans,sans-serif;font-size:100%;line-height:1.5}@media screen and (min-width:737px){html{font-size:1.125rem}}.custom-select{display:inline-block;box-sizing:border-box;padding:.5rem 2rem .5rem .8rem;width:auto;font-size:1em;line-height:1.3;border:1px solid #6c7782;box-shadow:none;border-radius:.5em;-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:transparent;background-image:url('data:image/svg+xml;c
 harset=US-ASCII,%3Csvg width="14" height="8" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M2 0L7 5L12 0L14 1L7 8L0 1L2 0Z" fill="%23555D66"/%3E%3C/svg%3E%0A');background-repeat:no-repeat;background-position:right .7em top 50%;background-size:.65em auto}.custom-select::-ms-expand{display:none}.custom-select:focus{box-shadow:0 0 1px 3px rgba(59,153,252,.7);box-shadow:0 0 0 3px -moz-mac-focusring;color:#222;outline:none}.custom-select option{font-weight:400}html{font-size:1rem}@media screen and (min-width:737px){html{font-size:1rem}}.screen-reader-text{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;color:#21759b;display:block;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-in
 dex:100000}.site-content[tabindex="-1"]:focus{outline:0}.no-js .hide-if-no-js{display:none}.alignleft{display:inline;float:left;margin-right:1.5em}.alignright{display:inline;float:right;margin-left:1.5em}.aligncenter{clear:both;display:block;margin-left:auto;margin-right:auto}@media screen and (max-width:480px){.alignleft,.alignright{display:block;float:none;margin-left:auto;margin-right:auto}}.button,.button-primary,.button-secondary,.plugin-upload-form .button-primary{border:1px solid;border-radius:3px;box-sizing:border-box;cursor:pointer;display:inline-block;font-size:.8rem;height:1.5625rem;line-height:1;margin:0;padding:0 .8rem;text-decoration:none;white-space:nowrap;-webkit-appearance:none}button::-moz-focus-inner,input[type=button]::-moz-focus-inner,input[type=reset]::-moz-focus-inner,input[type=submit]::-moz-focus-inner{border:0;padding:0}.button-group.button-xl .button,.button.button-xl{font-size:1rem;height:2.44140625rem;line-height:1;padding:0 1.5rem}.button-grou
 p.button-large .button,.button.button-large{height:1.953125rem;line-height:1;padding:0 1rem}.button-group.button-small .button,.button.button-small{font-size:.64rem;height:1.25rem;line-height:1;padding:0 .5rem}a.button,a.button-primary,a.button-secondary{line-height:1.5625rem}.button-group.button-large a.button,a.button.button-large{line-height:1.953125rem}.button-group.button-xl a.button,a.button.button-xl{line-height:2.44140625rem}.button-group.button-small a.button,a.button.button-small{line-height:1.25rem}.button:active,.button:focus{outline:none}.button.hidden{display:none}input[type=reset],input[type=reset]:active,input[type=reset]:focus,input[type=reset]:hover{background:none;border:none;box-shadow:none;padding:0 2px 1px;width:auto}.button,.button-secondary,.button:visited{background:#f7f7f7;border-color:#ccc;box-shadow:0 1px 0 #ccc;color:#555;vertical-align:top}p .button{vertical-align:baseline}.button-secondary:focus,.button-secondary:hover,.button.focus,.button.hover,.butt
 on:focus,.button:hover{background:#fafafa;border-color:#999;color:#23282d}.button-link:focus,.button-secondary:focus,.button.focus,.button:focus{border-color:#5b9dd9;box-shadow:0 0 3px rgba(0,115,170,.8)}.button-secondary:active,.button.active,.button.active:hover,.button:active{background:#eee;border-color:#999;box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);transform:translateY(1px)}.button.active:focus{border-color:#5b9dd9;box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5),0 0 3px rgba(0,115,170,.8)}.button-disabled,.button-secondary.disabled,.button-secondary:disabled,.button-secondary[disabled],.button.disabled,.button:disabled,.button[disabled]{background:#f7f7f7!important;border-color:#ddd!important;box-shadow:none!important;color:#a0a5aa!important;cursor:default;text-shadow:0 1px 0 #fff!important;transform:none!important}.button-link,input[type=submit].button-link{background:none;border:0;border-radius:0;box-shadow:none;cursor:pointer;margin:0;outline:none;padding:0}.button-link:
 focus{outline:1px solid #5b9dd9}.button-primary,.download-button,.plugin-upload-form .button-primary{text-decoration:none;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799}.button-primary,.button-primary:visited,.download-button,.download-button:visited,.plugin-upload-form .button-primary,.plugin-upload-form .button-primary:visited{background:#0085ba;border-color:#0073aa #006799 #006799;box-shadow:0 1px 0 #006799;color:#fff}.button-primary.focus,.button-primary.hover,.button-primary:focus,.button-primary:hover,.download-button.focus,.download-button.hover,.download-button:focus,.download-button:hover,.plugin-upload-form .button-primary.focus,.plugin-upload-form .button-primary.hover,.plugin-upload-form .button-primary:focus,.plugin-upload-form .button-primary:hover{background:#008ec2;border-color:#006799;box-shadow:0 1px 0 #006799;color:#fff}.button-primary.focus,.button-primary:focus,.download-button.focus,.download-button:focus,.plugin-upload-fo
 rm .button-primary.focus,.plugin-upload-form .button-primary:focus{box-shadow:0 1px 0 #0073aa,0 0 2px 1px #33b3db}.button-primary.active,.button-primary.active:focus,.button-primary.active:hover,.button-primary:active,.download-button.active,.download-button.active:focus,.download-button.active:hover,.download-button:active,.plugin-upload-form .button-primary.active,.plugin-upload-form .button-primary.active:focus,.plugin-upload-form .button-primary.active:hover,.plugin-upload-form .button-primary:active{background:#0073aa;border-color:#006799;box-shadow:inset 0 2px 0 #006799;vertical-align:top}.button-primary.disabled,.button-primary:disabled,.button-primary[disabled],.download-button.disabled,.download-button:disabled,.download-button[disabled],.plugin-upload-form .button-primary.disabled,.plugin-upload-form .button-primary:disabled,.plugin-upload-form .button-primary[disabled]{background:#008ec2!important;border-color:#007cb2!important;box-shadow:none!important;color:#66c6e4!impo
 rtant;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.button-primary.button.button-hero,.download-button.button.button-hero,.plugin-upload-form .button-primary.button.button-hero{box-shadow:0 2px 0 #006799}.button-primary.button.button-hero.active,.button-primary.button.button-hero.active:focus,.button-primary.button.button-hero.active:hover,.button-primary.button.button-hero:active,.download-button.button.button-hero.active,.download-button.button.button-hero.active:focus,.download-button.button.button-hero.active:hover,.download-button.button.button-hero:active,.plugin-upload-form .button-primary.button.button-hero.active,.plugin-upload-form .button-primary.button.button-hero.active:focus,.plugin-upload-form .button-primary.button.button-hero.active:hover,.plugin-upload-form .button-primary.button.button-hero:active{box-shadow:inset 0 3px 0 #006799}.button-primary-disabled{background:#008ec2!important;border-color:#007cb2!important;box-shadow:none!important;color:#66
 c6e4!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.button-group{display:inline-block;font-size:0;position:relative;vertical-align:middle;white-space:nowrap}.button-group>.button{border-radius:0;display:inline-block;margin-right:-1px;z-index:10}.button-group>.button-primary{z-index:100}.button-group>.button:hover{z-index:20}.button-group>.button:first-child{border-radius:3px 0 0 3px}.button-group>.button:last-child{border-radius:0 3px 3px 0}.button-group>.button:focus{position:relative;z-index:1}@media screen and (max-width:737px){.button,.button.button-large,.button.button-small,.plugin-upload-form .button-primary{font-size:14px;height:auto;line-height:normal;margin-bottom:4px;padding:6px 14px;vertical-align:middle}}.clear:after,.clear:before,.comment-content:after,.comment-content:before,.entry-content:after,.entry-content:before,.home-below:after,.home-below:before,.site-content:after,.site-content:before,.site-footer:after,.site-footer:
 before,.site-header:after,.site-header:before{content:"";display:table;table-layout:fixed}.clear:after,.comment-content:after,.entry-content:after,.home-below:after,.site-content:after,.site-footer:after,.site-header:after{clear:both}p.subheading{color:#82878c;font-weight:300;margin:-.4rem auto 2rem;text-align:center}p.intro,p.subheading{font-size:1.25rem}p.aside{font-size:.8rem}p.note{font-size:.64rem;letter-spacing:.01rem;max-width:18.1898940355rem}input,textarea{box-sizing:border-box}input[type=checkbox],input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=radio],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{background-color:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);color:#32373c;outline:none;transition:border-color .05s ease-in-out}input[type=checkbox]:foc
 us,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=radio]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}input[type=email],input[type=url]{direction:ltr}input[type=number]{height:28px;line-height:inherit}input[type=checkbox],input[type=radio]{background:#fff;border:1px solid #b4b9be;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);clear:none;color:#555;cursor:pointer;display:inline-block;height:16px;line-height:0;margin:-4px 4px 0 0;min-width:16px;outline:0;padding:0!important;text-align:center;transition:border-color .05s ease-in-out;vertical-align:middle;width:16px;-webkit-appearance:none}input[type=checkbox]:checked:before,input[type=radi
 o]:checked:before{display:inline-block;float:left;font:normal 21px/1 dashicons;vertical-align:middle;width:16px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}input[type=checkbox]:checked:before{color:#1e8cbe;content:"";margin:-3px 0 0 -4px}input[type=radio]{border-radius:50%;line-height:10px;margin-right:4px}input[type=radio]:checked+label:before{color:#82878c}input[type=radio]:checked:before{background-color:#1e8cbe;border-radius:50px;content:"•";font-size:24px;height:6px;line-height:16px;margin:4px;text-indent:-9999px;width:6px}input[type=reset]:active,input[type=reset]:hover{color:#00a0d2}input[type=search]{-webkit-appearance:te
 xtfield}input[type=search]::-webkit-search-decoration{display:none}button,input,select,textarea{font-family:inherit;font-size:inherit;font-weight:inherit}input,select,textarea{border-radius:0;font-size:14px;padding:3px 5px}textarea{line-height:1.4;overflow:auto;padding:2px 6px;resize:vertical}textarea.code{line-height:1.4;padding:4px 6px 1px}label{cursor:pointer;vertical-align:middle}input,select{margin:1px;padding:3px 5px}input.code{padding-top:6px}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}.wp-core-ui :-moz-placeholder,:-moz-placeholder{color:#a9a9a9}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:hsla(0,0%,100%,.5);border-color:hsla(0,0%,87.1%,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:none;box-shadow:none}input.large-text,textare
 a.large-text{width:99%}input.regular-text{width:25em}input.small-text{padding:1px 6px;width:50px}input[type=number].small-text{width:65px}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=email],input[type=number],input[type=password],input[type=search],input[type=text]{-webkit-appearance:none;padding:6px 10px}input[type=number]{height:40px}input.code{padding-bottom:5px;padding-top:10px}input[type=checkbox]{-webkit-appearance:none;padding:10px}input[type=checkbox]:checked:before{font:normal 30px/1 dashicons;margin:-3px -5px}input[type=checkbox],input[type=radio]{height:25px;width:25px}input[type=radio]:checked:before{vertical-align:middle;width:9px;height:9px;margin:7px;line-height:16px}input,textarea{font-size:16px}input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:55px;display:inline;padding:3px 6
 px;margin:0 3px}input.regular-text{width:100%}label{font-size:14px}fieldset label{display:block}}a.button:active,a.button:focus,a.button:hover{text-decoration:none}.notice{background:#fff;border-left:4px solid #fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:1em 0;padding:1px 12px}.notice p{font-size:.8rem;margin:.5em 0;padding:2px}.notice.notice-alt{box-shadow:none}.notice.notice-large{padding:10px 20px}.notice.notice-success{border-left-color:#46b450}.notice.notice-success.notice-alt{background-color:#ecf7ed}.notice.notice-warning{border-left-color:#ffb900}.notice.notice-warning.notice-alt{background-color:#fff8e5}.notice.notice-error{border-left-color:#dc3232}.notice.notice-error.notice-alt{background-color:#fbeaea}.notice.notice-info{border-left-color:#00a0d2}.notice.notice-info.notice-alt{background-color:#e5f5fa}.error-404 .page-content,.error-404 .page-title{text-align:center}.error-404 .page-content .logo-swing{height:10rem;margin:6rem auto;position:relative;text-align:cent
 er;width:10rem}.error-404 .page-content .logo-swing .wp-logo{left:0;max-width:none;position:absolute;top:0;width:10rem}@keyframes hinge{10%{width:180px;height:180px;transform:rotate(0deg)}15%{width:185px;height:185px;transform:rotate(0deg)}20%{width:180px;height:180px;transform:rotate(5deg)}40%{transform-origin:top left;animation-timing-function:ease-in-out}60%{transform:rotate(40deg);transform-origin:top left;animation-timing-function:ease-in-out}40%,80%{transform:rotate(60deg);transform-origin:top left;animation-timing-function:ease-in-out;opacity:1}to{transform:translate3d(0,700px,0);opacity:0}}.hinge{animation-duration:2s;animation-name:hinge}.comments-area{margin-top:5em}.comments-area>:last-child{margin-bottom:0}.comments-area .comment-list+.comment-respond{border-top:1px solid #eaeaea}.comments-area .comment-list+.comment-respond,.comments-area .comment-navigation+.comment-respond{padding-top:1.6em}.comments-area .comments-title{margin-bottom:1.3333em}.comments-area .comme
 nt-list{list-style:none;margin:0}.comments-area .comment-list .pingback,.comments-area .comment-list .trackback,.comments-area .comment-list article{border-top:1px solid #eaeaea;padding:1.6em 0}.comments-area .comment-list article:not(:only-child){padding-bottom:0}.comments-area .comment-list article+.comment-respond{padding-bottom:1.6em}.comments-area .comment-list .children{list-style:none;margin:0}.comments-area .comment-list .children>li{padding-left:.8em}.comments-area .comment-list .alt{background:none}.comments-area .comment-author{color:#999;margin-bottom:.4em}.comments-area .comment-author .avatar{float:left;height:24px;margin-right:.8em;width:24px}.comments-area .comment-metadata,.comments-area .pingback .edit-link{color:#999;line-height:1.5}.comments-area .comment-metadata a,.comments-area .pingback .edit-link a{color:#777}.comments-area .comment-metadata{font-size:.8rem;margin-bottom:1.6em}.comments-area .comment-metadata .edit-link,.comments-area .pingback .edit-link
 {margin-left:1em}.comments-area .pingback .edit-link:before{top:5px}.comments-area .comment-content ol,.comments-area .comment-content ul{margin:0 0 1.6em 1.3333em}.comments-area .comment-content>:last-child,.comments-area .comment-content li>ol,.comments-area .comment-content li>ul{margin-bottom:0}.comments-area .comment-content .reply{font-size:12px}.comments-area .comment-content .reply a{border:1px solid #eaeaea;color:#707070;display:inline-block;font-weight:700;line-height:1;margin-top:2em;padding:.4167em .8333em;text-transform:uppercase}.comments-area .comment-content .reply a:focus,.comments-area .comment-content .reply a:hover{border-color:#333;color:#333;outline:0}.comments-area .comment-reply-title a{font-weight:inherit}.comments-area .comment-form label{font-size:.8rem;font-weight:700;display:block;letter-spacing:.04em;line-height:1.5}.comments-area .comment-form input[type=email],.comments-area .comment-form input[type=text],.comments-area .comment-form input[ty
 pe=url],.comments-area .comment-form textarea{width:100%}.comments-area .comment-awaiting-moderation,.comments-area .comment-notes,.comments-area .form-allowed-tags,.comments-area .logged-in-as{font-size:1rem;line-height:1.5;margin-bottom:2em}.comments-area .no-comments{border-top:1px solid #eaeaea;color:#999;font-weight:700;padding-top:1.6em}.comments-area .comment-navigation+.no-comments{border-top:0}.comments-area .form-allowed-tags code{font-family:Inconsolata,monospace}.comments-area .form-submit{margin-bottom:0}.comments-area .required{color:#c0392b}.entry-content{hyphens:auto;word-wrap:break-word}.entry-content>p:first-child{margin-top:0}.entry-content [class*=col-]~h1,.entry-content [class*=col-]~h2,.entry-content [class*=col-]~h3,.entry-content [class*=col-]~h4,.entry-content [class*=col-]~h5,.entry-content [class*=col-]~h6{clear:none}.entry-header{position:relative}.entry-header .sticky-post{color:#999;font-size:.8rem;font-style:italic;position:absolute;top:-.8rem}.entr
 y-meta{color:#999;font-size:.8rem;margin-bottom:1rem}.entry-meta a{color:#777}.entry-meta>span{margin-right:1rem}.entry-meta>span :last-of-type{margin:0}.entry-meta .byline,.entry-meta .updated:not(.published),.sticky .entry-meta .posted-on{display:none}.group-blog .entry-meta .byline,.single .entry-meta .byline{display:inline}.entry-summary{hyphens:auto;word-wrap:break-word}body:not(.single):not(.search) .site-main .post{margin-bottom:3.0517578125rem;max-width:40em}.gallery{margin-bottom:1.5rem}.gallery .gallery-item{display:inline-block;margin:0;text-align:center;vertical-align:top;width:100%}.gallery.gallery-columns-2 .gallery-item{max-width:50%}.gallery.gallery-columns-3 .gallery-item{max-width:33.33%}.gallery.gallery-columns-4 .gallery-item{max-width:25%}.gallery.gallery-columns-5 .gallery-item{max-width:20%}.gallery.gallery-columns-6 .gallery-item{max-width:16.66%}.gallery.gallery-columns-7 .gallery-item{max-width:14.28%}.gallery.gallery-columns-8 .gallery-item{max-width
 :12.5%}.gallery.gallery-columns-9 .gallery-item{max-width:11.11%}.gallery .gallery-caption{display:block}.main-navigation{background:#0073aa;clear:both;left:0;position:absolute;top:60px;width:100%}.main-navigation ul{display:none;list-style:none;margin:0;padding-left:0}.main-navigation ul ul{box-shadow:0 3px 3px rgba(0,0,0,.2);float:left;left:-999em;position:absolute;top:1.5em;z-index:99999}.main-navigation ul ul ul{left:-999em;top:0}.main-navigation ul ul li.focus>ul,.main-navigation ul ul li:hover>ul{left:100%}.main-navigation ul ul a{width:200px}.main-navigation ul li.focus>ul,.main-navigation ul li:hover>ul{left:auto}.main-navigation li{border-top:1px solid hsla(0,0%,100%,.2);padding:1rem}.main-navigation a{color:hsla(0,0%,100%,.8);display:block;font-size:.8rem;text-decoration:none}.main-navigation a.active,.main-navigation a:hover{color:#fff}@media screen and (min-width:737px){.main-navigation a.active{border-bottom:1px solid}}.main-navigation.toggled{z-index:1}.mai
 n-navigation.toggled ul{display:block}.menu-toggle{background:transparent;border:none;color:#fff;height:3.5rem;position:absolute;right:1rem;top:-58px;width:3.5rem}.toggled .menu-toggle:before{content:""}@media screen and (min-width:737px){.menu-toggle{display:none}.main-navigation{float:right;position:static;width:auto}.main-navigation.toggled{padding:1px 0}.main-navigation ul{display:inline-block;font-size:0}.main-navigation ul li{border:0;display:inline-block;font-size:1rem;margin-right:1rem;padding:0}.main-navigation ul li:last-of-type{margin-right:0}}.comment-content .wp-smiley,.entry-content .wp-smiley,.page-content .wp-smiley{border:none;margin-bottom:0;margin-top:0;padding:0}embed,iframe,object{max-width:100%}body.page .gutters .col-12{width:100%}body.page .entry-header{background:#0073aa;padding:1rem 0}body.page .entry-header .entry-title{color:#fff;font-size:1.5625rem;font-weight:300;line-height:1;margin:0 auto;padding:0 1.5625rem}body.page .entry-header.home{p
 adding:1.5625rem 1.143rem;text-align:center}@media screen and (min-width:737px){body.page .site-header+.site-main .entry-title{padding:initial}}body.page .entry-content,body.page .entry-footer{margin:0 auto;max-width:960px;padding:3.0517578125rem 1.5625rem}.post-navigation{margin:5em auto;padding:0}.post-navigation a{border-bottom:1px solid #eaeaea;color:#444;display:block;font-weight:600;padding:11px 0 12px;text-transform:none;width:100%}.post-navigation a:hover{color:#21759b}.post-navigation .nav-links{border-top:1px solid #eaeaea;hyphens:auto;word-wrap:break-word}.post-navigation .meta-nav{color:#777;display:block;font-size:13px;line-height:2;text-transform:uppercase}.post-navigation .nav-next{text-align:right}.pagination .nav-links{text-align:center}.pagination .nav-links .page-numbers{background-color:#f9f9f9;cursor:hand;display:inline-block;min-width:2em;padding:8px}.pagination .nav-links .page-numbers.dots,.pagination .nav-links .page-numbers.next,.pagination .nav-links .page
 -numbers.prev{background:none;font-size:.9em;width:auto}.pagination .nav-links .page-numbers.dots{cursor:inherit}@media screen and (max-width:737px){.pagination .nav-links .page-numbers.next,.pagination .nav-links .page-numbers.prev{font-size:0;min-width:0;padding:0}.pagination .nav-links .page-numbers.next:after,.pagination .nav-links .page-numbers.prev:before{background-color:#f9f9f9;display:inline-block;font-size:1rem;line-height:1.5;min-width:2em;padding:8px}.pagination .nav-links .page-numbers.prev:before{content:"‹"}.pagination .nav-links .page-numbers.next:after{content:"›"}}.pagination .nav-links span.page-numbers{background-color:#f7f7f7;font-weight:700}.search-form .search-field{line-height:normal;margin:0;padding:4px 5px;vertical-align:text-bottom}body.search .gutters .col-12{width:100%}body.search .site-main{margin:0 auto;max-width:960px;padding:0 1.5625rem 3.0517578125rem}.site-content{max-width:960px;padding:0 1.5625rem}@media screen and (min-wi
 dth:737px){.site-content{padding:0 10px 3.0517578125rem}}@media screen and (max-width:737px){.site-content .site-main{float:none;margin:0;width:auto}}.home .site-content,.page .site-content,.site-content.page{margin:auto;max-width:none;padding:0}.site-content .page-title{font-size:1.25rem;font-weight:400}.site-content .no-results{margin:0 auto 3.0517578125rem;max-width:40em;padding:0 2rem}.site-description{color:hsla(0,0%,100%,.8);font-size:1.25rem;font-weight:300;margin:-.4rem auto 2rem;text-align:center}.site-header{background:#0073aa;padding:1rem 0;position:relative}.site-header .site-branding{margin:0 auto;max-width:960px;padding:0 1.5625rem}@media screen and (min-width:737px){.site-header .site-branding{padding:0 10px}}.site-header.home{padding:1.5625rem 1.143rem;text-align:center}.site-title{display:inline-block;font-size:1.5625rem;font-weight:300;line-height:1;margin:0 2rem 0 0;max-width:none}.site-title a{color:#fff;font-weight:300}.site-title a:active,.site-title a:focus,.s
 ite-title a:hover{text-decoration:none}.site-header.home .site-title{display:inherit;font-size:3.8146972656rem;margin:2rem 0 1rem}.widget-area{font-size:.8rem}@media screen and (min-width:480px) and (max-width:768px){.widget-area{display:flex}.widget-area .widget{width:48%}}#wporg-footer{background-color:#f7f7f7;border-top:1px solid #dfdfdf;padding:22px 14px 65px}#wporg-footer,#wporg-footer .wrapper{clear:both;margin:0 auto;overflow:auto}#wporg-footer .wrapper{max-width:930px}#wporg-footer ul{float:left;margin-bottom:20px;margin-left:24px;overflow:auto;padding-left:0;width:135px}@media screen and (min-width:960px){#wporg-footer ul:first-child{margin-left:0}}#wporg-footer ul li{color:#bbb;font-size:14px;list-style-type:none;margin-bottom:1px}#wporg-footer ul li a{text-decoration:none;text-decoration-skip-ink:none}#wporg-footer ul li a:hover{color:#0073aa;text-decoration:underline}#wporg-footer .cip{clear:both;color:#ccc;float:none;font-size:.8rem;letter-spacing:.3em;margin:35px auto 
 0;text-align:center;text-transform:uppercase}#wporg-footer .cip.cip-image{background:url(//s.w.org/style/images/codeispoetry.png?1=) 50% no-repeat;background-size:190px 15px;height:15px;text-indent:-9999px;width:190px}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:1.5dppx),only screen and (min-resolution:144dpi){#wporg-footer .cip.cip-image{background-image:url(//s.w.org/style/images/codeispoetry-2x.png?1=)}}@media screen and (min-width:561px) and (max-width:959px){#wporg-footer .wrapper{max-width:600px}#wporg-footer ul{margin-left:2%;width:32%}#wporg-footer ul:nth-child(3n+1){margin-left:0}#wporg-footer ul:nth-child(4n){clear:both}}@media screen and (max-width:560px){#wporg-footer .wrapper{max-width:360px}#wporg-footer ul{margin-left:4%;width:48%}#wporg-footer ul:nth-child(odd){margin-left:0;clear:both}}#wporg-header{background:#23282d;height:140px;position:relative;text-align:center;width:100%}#wporg-header .wrapper{margin:0 auto;max-wi
 dth:960px}#wporg-header h1{display:inline-block;margin:auto;width:303px}#wporg-header h1 a{background:url(//s.w.org/style/images/wporg-logo.svg?3=) 0 no-repeat;background-size:290px 46px;display:block;height:88px;text-indent:-9999px}#wporg-header h2.rosetta{clear:none;color:#dfdfdf;font-family:Georgia,Times New Roman,serif;font-size:30px;margin:0 0 0 60px}#wporg-header h2.rosetta a{border-bottom:none;color:#dfdfdf;display:block;height:52px;line-height:22px;padding:0}#wporg-header h2.rosetta a:hover{text-decoration:none}#wporg-header #wporg-header-menu{background:#23282d;left:-75%;list-style:none;margin:0;max-width:75%;min-width:200px;position:absolute;text-align:left;top:100%;transition:left .3s;z-index:100000}#wporg-header #wporg-header-menu.toggled{left:0}#wporg-header ul li{list-style-type:none;position:relative}#wporg-header ul li a{color:#eee;display:block;font-family:Open Sans,Helvetica,Arial,Liberation Sans,sans-serif;font-size:13px;font-weight:600;height:34px;line-height:34p
 x;margin:0 4px;padding:10px 30px;text-decoration:none}#wporg-header ul li a.subcurrent{font-weight:700}@media (max-width:768px){#wporg-header ul li a{height:auto}}#wporg-header ul li.current-menu-item a,#wporg-header ul li.current_page_parent a,#wporg-header ul li a.current,#wporg-header ul li a:hover{color:#00a0d2}#wporg-header ul li#download,#wporg-header ul li.download{float:right;height:34px;margin-right:14px;overflow:hidden;padding:0 0 34px}@media screen and (max-width:767px){#wporg-header ul li#download,#wporg-header ul li.download{display:block;float:none;margin:10px 20px 20px;padding-bottom:0;height:auto}#wporg-header ul li#download a,#wporg-header ul li.download a{padding:4px 10px;text-align:center}}#wporg-header ul li#download a,#wporg-header ul li.download a{margin:0;padding:0 16px}#wporg-header ul li#download a:hover,#wporg-header ul li.download a:hover{color:#eee}#wporg-header ul li#download.current,#wporg-header ul li#download.current-menu-item,#wporg-header ul li#down
 load .uparrow,#wporg-header ul li.download.current,#wporg-header ul li.download.current-menu-item,#wporg-header ul li.download .uparrow{display:none}#wporg-header ul li .nav-submenu{clip:rect(1px,1px,1px,1px);height:1px;left:-2px;margin:0;overflow:hidden;padding:0;position:absolute;width:1px;z-index:99999}#wporg-header ul li .nav-submenu li a{display:inline-block;height:24px;line-height:24px;margin:0;white-space:nowrap}@media screen and (min-width:768px){#wporg-header #head-search{float:right;margin-right:14px;padding-top:30px}}#wporg-header #head-search form{border-bottom:1px solid #3f3f3f;display:inline-block;margin-left:60px;width:288px}#wporg-header #head-search form input.text{background:#191e23;border:0;border-radius:0;box-sizing:content-box;color:#b4b9be;float:left;font-family:Open Sans,sans-serif;font-size:12px;height:24px;margin:0;outline:none;padding:3px;vertical-align:top;width:256px}#wporg-header #head-search form input.text::-moz-placeholder{color:#eee}@media screen and
  (max-width:480px){#wporg-header #head-search form input.text{width:216px}}#wporg-header #head-search form .button{background:#191e23 url(//s.w.org/wp-includes/images/admin-bar-sprite.png?d=20120831) no-repeat 2px 5px;border:none;border-radius:0;box-shadow:none;float:left;height:30px;margin:0;padding:0;text-shadow:none!important;width:26px}@media screen and (max-width:480px){#wporg-header #head-search form{width:248px}}@media screen and (min-width:480px){#wporg-header #head-search form{margin-left:0}}@media screen and (min-width:768px){#wporg-header{height:120px;text-align:inherit}#wporg-header h1{float:left;padding-left:10px}#wporg-header h2.rosetta{float:left;margin-left:0;padding:36px 27px 0}#wporg-header #headline h2{text-rendering:optimizeLegibility}#wporg-header #wporg-header-menu{float:left;height:46px;list-style:none;margin:-15px 0 0;max-width:inherit;min-width:0;padding:0;position:static;width:100%}#wporg-header ul li{float:left;position:relative}#wporg-header ul li a{heigh
 t:46px;padding:0 6px}#wporg-header ul li a.current~.uparrow{border-bottom:9px solid #f7f7f7;border-left:9px solid transparent;border-right:9px solid transparent;height:0;margin:-8px auto 0;width:0}#wporg-header ul li.current-menu-item:after,#wporg-header ul li.current_page_parent:after{border-bottom:9px solid #f7f7f7;border-left:9px solid transparent;border-right:9px solid transparent;content:"";height:0;left:50%;margin:-8px 0 0 -9px;position:absolute;width:0}#wporg-header ul li .nav-submenu:hover~.uparrow,#wporg-header ul li:hover .nav-submenu~.uparrow{border-bottom:9px solid #32373c;border-left:9px solid transparent;border-right:9px solid transparent;height:0;margin:-10px auto 0;width:0}#wporg-header ul li .nav-submenu{background:#32373c;border:1px solid #32373c;border-top:0;margin-top:-1px;min-width:0}#wporg-header ul li .nav-submenu li{float:none}#wporg-header ul li .nav-submenu li a{height:34px;line-height:34px}#wporg-header .nav-menu .focus>ul,#wporg-header .nav-m
 enu ul li:hover>ul,#wporg-header ul.nav-menu .focus>ul,#wporg-header ul.nav-menu li:hover>ul{clip:inherit;height:inherit;overflow:inherit;width:inherit}#wporg-header ul li.current-menu-item:after,#wporg-header ul li.current_page_parent:after,#wporg-header ul li a.current~.uparrow{border-bottom-color:#0073aa}}.page-download #wporg-header #download,.page-parent-download #wporg-header #download{display:none}#mobile-menu-button{background:none;border:none;box-shadow:none;display:block;float:left;font-family:dashicons;font-size:16px;font-style:normal;font-weight:400;left:10px;line-height:1;padding:1px;position:absolute;text-align:center;text-decoration:inherit;text-shadow:none;top:75px;transition:color .1s ease-in;vertical-align:top;-webkit-font-smoothing:antialiased}#mobile-menu-button:before{border:none;box-sizing:border-box;color:#888;content:"";display:inline-block;float:left;font:normal 50px/1 Dashicons;margin:0;outline:none;padding:3px;text-decoration:none;ver
 tical-align:middle;-webkit-font-smoothing:antialiased}@media screen and (min-width:768px){#mobile-menu-button{display:none}}#download-mobile{background:#f7f7f7;border-bottom:1px solid #ddd}#download-mobile .wrapper{padding:20px 0;text-align:center}#download-mobile span.download-ready{font-size:1.6em;margin:0 .25em}#download-mobile a.download-button{font-size:1.6em;height:inherit;margin:10px .25em;padding:10px 15px}.category-context__bar{margin:0 1.5rem;background:#edeff0;border-radius:2px;font-size:.8125rem;overflow:auto;transition:all 50ms ease-out}.category-context__bar>div{display:flex;align-items:center;justify-content:space-between}@media only screen and (min-width:782px){.category-context__bar{margin:0 1.5rem}}@media only screen and (min-width:960px){.category-context__bar{margin:0 auto;max-width:960px}}.category-context__bar ul{margin:0;padding:0;display:flex;justify-content:space-between}.category-context__bar ul li{list-style:none;font-size:.8125rem}.category-context__ba
 r ul li a{display:block;padding:1.125rem .75rem;text-decoration:none}.category-context__bar ul li:last-child a{padding-right:1.5rem}.category-context__bar__copy{margin:0;padding:1.125rem 1.5rem;font-size:.8125rem;font-weight:400}.category-context__bar__title{margin:0;padding-right:1.5rem;color:#555d66;font-size:.75rem;font-weight:400;text-transform:uppercase}.category-context__bar__links{display:flex;align-items:center}@media only screen and (max-width:782px){.category-context__bar__links{display:none}}.category-context__bar--is-hidden{height:0;overflow:hidden}.category-menu{margin:0;padding:0;position:relative;background:linear-gradient(180deg,hsla(0,0%,100%,0) 94%,#0073aa 0);background-repeat:no-repeat;background-size:0;background-position-x:20px;transition:all 75ms ease-out}.category-menu li{display:inline-block;margin:0;list-style:none}.category-menu a{display:block;padding:.75rem;color:#40464d;font-size:.875rem;text-decoration:none}.category-menu a:active,.category-menu a:focus
 ,.category-menu a:hover,li .category-menu--is-active{color:#000}.category-menu__mobile{padding:0!important;border-top:none!important}.category-menu__mobile ul{margin:0;padding:0;background:#23282d}.category-menu__mobile li{list-style:none;border-top:1px solid #32373c}.category-menu__mobile li a{display:block;padding:1rem 1.5rem;font-size:.875rem;text-decoration:none;color:#ccd0d4}.category-menu__mobile>.components-panel__body-title{margin:0!important}.category-menu__mobile>.components-panel__body-title>button{padding:1.5rem}.category-menu--is-loading{height:24px;position:relative}.category-menu--is-loading:after{content:"";position:absolute;background:#f3f4f5;border-radius:4px;width:80%;height:24px;left:0;transition:none}.category-search{display:flex;align-items:center;background:#fff;border:1px solid #6c7782;border-radius:2px}.category-search input[type=search]{flex-grow:1;margin:0;padding:.25rem .5rem;border:none;box-shadow:none;font-size:.8125rem}.category-sear
 ch__button{display:flex;background:transparent;border:none;color:#6c7782}.category-search--is-loading{display:block;height:24px;min-width:100%;background:#f3f4f5;border-radius:4px}@media only screen and (min-width:480px){.category-search--is-loading{width:224px}}.pattern__copy-button{transition:all 75ms ease-in-out}.pattern__copy-button.is-small{font-size:.75rem;padding:.75rem;height:auto}.pattern__favorite-button{position:relative;font-size:.875rem;height:2.25rem;width:2.25rem;border-radius:2px;color:#606a74}.pattern__favorite-button svg{position:absolute;top:calc(50% - .75rem);left:calc(50% - .75rem);height:1.5rem;width:1.5rem;transition:all .15s ease-out}.pattern__favorite-button svg path{fill:#6c7782}.pattern__favorite-button .pattern__favorite-filled{opacity:0}.pattern__favorite-button:hover{color:#555d66;background:transparent}.pattern__favorite-button:hover svg path{fill:#555d66}.pattern__favorite-button:active{background:transparent;box-shadow:none;transform:none}.pattern__f
 avorite-button.is-favorited{color:#555d66}.pattern__favorite-button.is-favorited svg path{fill:#d94f4f}.pattern__favorite-button.is-favorited .pattern__favorite-outline{opacity:0;transform:scale(2.8)}.pattern__favorite-button.is-favorited .pattern__favorite-filled{opacity:1}.pattern__favorite-button.is-favorited:hover .pattern__favorite-filled{animation:HeartBeat .9s infinite}@media (prefers-reduced-motion){.pattern__favorite-button.is-favorited:hover .pattern__favorite-filled{animation:none}}.pattern__favorite-button.has-label{padding:12px 18px 12px 38px;height:auto;width:auto}.pattern__favorite-button.has-label svg{top:calc(50% - 12px);left:9px}@keyframes HeartBeat{0%{transform:scale(1)}25%{transform:scale(1.2)}40%{transform:scale(1)}60%{transform:scale(1.2)}to{transform:scale(1)}}.main-navigation{float:none;position:static;width:auto}.main-navigation a{font-size:.8125rem}.main-navigation.toggled div.menu{position:absolute;top:57px;right:0;width:100%;background:#0073aa}.menu-toggl
 e{position:static;height:auto;width:auto;font-size:1.5625rem;overflow:hidden;-webkit-appearance:none}body.page .entry-header{background:none;padding:0}body.page .entry-header .entry-title{color:inherit;margin:2rem auto 1rem;max-width:960px}@media screen and (min-width:737px){body.page .entry-header .entry-title{padding:0 10px}}.pattern-grid-menu{margin:0 auto;max-width:960px;display:flex;flex-direction:column;justify-content:space-between;align-items:center}.pattern-grid-menu>:first-child,.pattern-grid-menu>:last-child{width:100%}.pattern-grid-menu>:last-child{margin:1.5rem;width:calc(100% - 3rem)}@media only screen and (min-width:782px){.pattern-grid-menu{margin:1.5rem;flex-direction:row}.pattern-grid-menu>:last-child{margin:0;width:auto}}@media only screen and (min-width:960px){.pattern-grid-menu{margin:1.5rem auto}}.pattern-grid{max-width:960px;margin:1.5rem}@media screen and (min-width:600px){.pattern-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(28
 0px,1fr));gap:1.5rem}.pattern-grid>*{align-self:baseline}}@media screen and (min-width:960px){.pattern-grid{margin-left:auto;margin-right:auto}}.pattern-grid__pattern{position:relative;margin:0 0 1.5rem;border:1px solid #d7dade;border-radius:2px;transition:all 75ms ease-in-out}@media screen and (min-width:600px){.pattern-grid__pattern{display:inline-block;margin:0}}.pattern-grid__pattern .pattern-grid__preview{overflow:hidden}.pattern-grid__pattern .pattern-grid__actions{position:absolute;right:0;bottom:0;left:0;display:flex;align-items:center;padding:.375rem;background:hsla(0,0%,100%,.8);backdrop-filter:blur(3px);opacity:0;transform:translateY(6px);transition:all 75ms ease-in-out}.pattern-grid__pattern .pattern-grid__actions .pattern-grid__title{flex-grow:1;margin:0;padding:0 .375rem 0 .75rem;font-size:.75rem;pointer-events:none}.pattern-grid__pattern .pattern-grid__actions .pattern__copy-button,.pattern-grid__pattern .pattern-grid__actions .pattern__favorite-button{flex-shrink:
 0}.pattern-grid__pattern .pattern-grid__actions .button+.button{margin-left:.375rem}.pattern-grid__pattern:focus-within .pattern-grid__actions,.pattern-grid__pattern:hover .pattern-grid__actions{opacity:1;transform:translateY(0)}.pattern-preview__container{padding:2rem 0 0;background:#f3f4f5}.pattern-preview__viewport{position:relative;margin:0 auto;padding:0 20px;max-width:100vw;min-width:320px}.pattern-preview__viewport .pattern-preview__viewport-iframe{background:#fff;border:1px solid #e8eaeb;vertical-align:middle;max-width:100vw}.pattern-preview__viewport:focus-within .pattern-preview__resize-help{clip:auto;clip-path:none;height:auto;margin:initial;overflow:initial;width:auto;bottom:-1rem;left:20px;right:20px;padding:8px 16px;background:#fff;border-radius:2px;border:1px solid #d7dade;text-align:center}.pattern-preview__drag-handle{position:absolute;top:0;bottom:0;width:20px}.pattern-preview__drag-handle.is-left{left:0}.pattern-preview__drag-handle.is-right{right:0}.pattern-previ
 ew__drag-handle-button{position:absolute;top:calc(50% - 50px);left:6px;padding:0;width:8px;height:100px;appearance:none;cursor:grab;outline:none;background:#7e8993;border-radius:99999px;border:none}.pattern-preview__drag-handle-button:hover{background:#6c7782}.pattern-preview__drag-handle-button:active{cursor:grabbing;background:#606a74}.pattern-preview__drag-handle-button:focus{box-shadow:0 1px 0 #0073aa,0 0 2px 1px #33b3db}body.single-wporg-pattern{box-sizing:border-box;font-size:14px;font-weight:400;line-height:1.2}body.single-wporg-pattern .site-content{margin:auto;max-width:none;padding:0}body.single-wporg-pattern .entry-header{max-width:960px;padding:2rem 0;margin-left:auto;margin-right:auto}body.single-wporg-pattern .entry-header .entry-title{margin-top:0;line-height:1.2}body.single-wporg-pattern .pattern-actions{display:flex;align-items:stretch}body.single-wporg-pattern .pattern-actions button+button{margin-left:2em}body.single-wporg-pattern .entry-content{max-width:960px;ma
 rgin-left:auto;margin-right:auto}body.single-wporg-pattern .pattern__meta{padding:2rem 0;background:#f3f4f5}body.single-wporg-pattern .pattern__meta>div{max-width:960px;margin-left:auto;margin-right:auto;display:flex;justify-content:space-between}body.single-wporg-pattern .pattern__meta .pattern-preview__report{text-align:right}.site-header:not(.home) .search-form{display:flex;align-items:center}.site-header:not(.home) .search-form>input{flex:1;border:0;border-radius:2px 0 0 2px;display:inline-block;font-size:12px;padding:5px 10px;position:relative;width:auto;height:100%}.site-header:not(.home) .search-form button{margin:0;border-radius:0 2px 2px 0;padding:3px 12px;height:unset}.search-form--is-inline .search-form{display:flex;justify-content:space-between;background:#fff}.search-form--is-inline .search-form>label{flex:1}.search-form--is-inline .search-form input{padding:.5rem;background:transparent;border:none;box-shadow:none;width:100%;font-size:14px}@media only screen an
 d (min-width:768px){.search-form--is-inline .search-form input{font-size:16px}}.search-form--is-inline .search-form button{background:transparent;margin-bottom:0;border:0;box-shadow:none;height:inherit;text-shadow:none;color:#32373c}.search-form--is-inline .search-form button:focus{-webkit-box-shadow:0 0 2px 1px #0073aa;box-shadow:0 0 2px 1px #0073aa}.search-form--is-centered .search-form{margin:0 auto}.search-form--is-constrained .search-form{max-width:36rem}.search-form--is-muted .search-form{border-color:#d7dade!important}.search-form--is-muted .search-form button,.search-form--is-muted .search-form input{background:#f8f9f9;color:#7e8993}.search-form--has-medium-text .search-form input{font-size:14px}.search-form--has-border .search-form{border:1px solid #7e8993}.section-heading_link,.section-heading_title{margin-bottom:0}.section-heading_title{font-weight:300}.section-heading_title .archive-title-prefix{display:block;font-size:1rem}.section-heading_link{text-decoration:underline
 ;font-weight:600;margin-top:1.5rem!important}@media only screen and (min-width:768px){.section-heading_link{margin-top:0!important}}.section-heading_description{margin:1rem 0 0}.section-heading_description :last-child{margin-bottom:0}.section-heading--with-space{padding-bottom:16px}.site-content{margin:0 auto;max-width:none;padding:0}body.home .site-header{padding:3.75rem 1rem;text-align:left}body.home .site-branding{display:grid;grid-template-rows:auto 1fr;grid-template-columns:1fr 22rem}body.home .site-branding>*{align-self:center}@media screen and (max-width:736px){body.home .site-branding{display:block}}body.home .site-title.site-title{grid-column-start:1;grid-row-start:1;margin-top:0;text-align:left;font-size:3rem;line-height:1.25}body.home .site-description{grid-column-start:1;grid-row-start:2;margin:0;font-size:1.25rem;line-height:1.6;text-align:left;color:#fff}body.home .site-callout{grid-column-start:2;grid-row-start:1;grid-row-end:span 2;margin-left:4rem;padding:1.125re
 m 1.5rem 1.5rem;font-size:.875rem;line-height:1.6;background:#fff;box-shadow:.75rem .75rem 0 rgba(0,0,0,.15)}body.home .site-callout h2{margin-top:0;font-size:1.125rem;line-height:1.25;font-weight:600}body.home .site-callout p:last-child{margin-bottom:0}@media screen and (max-width:736px){body.home .site-callout{margin:2rem auto 0;max-width:24rem}}body:not(.home) .site-branding{display:flex;align-items:center;justify-content:space-between;font-size:.8125rem;color:#fff}body:not(.home) .site-branding a{color:#fff}body:not(.home) .site-branding .sep{margin-left:.5rem;margin-right:.5rem}body:not(.home) .site-branding .is-current-page{font-weight:600}.site-title a{text-decoration:none}.site-title a:active,.site-title a:focus,.site-title a:hover{color:#fff}.has-wporg-blue-color{color:#1e8cbe}.has-wporg-blue-background-color{background-color:#1e8cbe}.has-wporg-purple-color{color:#826eb4}.has-wporg-purple-background-color{background-color:#826eb4}.has-wporg-white-color{color:#fff}.has-wporg
 -white-background-color{background-color:#fff}.home-page .shapes{position:relative;margin:0 auto}.home-page .shapes .parallelogram p:before{font-size:64px;height:64px;left:-16px;position:relative}.home-page .shapes .parallelogram{color:#fff;display:block;margin:0 auto;opacity:.9;padding:60px 40px;text-align:center;text-decoration:none}.home-page .shapes strong{display:block;font-size:28px;font-weight:300;padding-bottom:15px;padding-top:15px}.home-page .shapes p{color:#fff;font-size:16px;font-weight:300;margin:0}.home-page .shapes u{display:block;font-size:18px;padding-top:15px}@media only screen and (min-width:768px){.home-page .shapes{height:400px}.home-page .shapes .parallelogram{width:50%;position:absolute;padding:50px 90px}}@media only screen and (min-width:960px){.home-page .shapes .parallelogram{-webkit-transform:skew(-15deg);-ms-transform:skew(-15deg);transform:skew(-15deg)}.home-page .shapes .parallelogram:before,.home-page .shapes p{-webkit-transform:skew(15deg);-ms-transfo
 rm:skew(15deg);transform:skew(15deg)}}@media only screen and (min-width:1200px){.home-page .shapes{margin:0 -60px}}.terms{font-style:italic;font-size:14px}
</del><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+@charset "UTF-8";[class*=col-]{margin:inherit}.row{display:flex;flex-direction:row;flex-wrap:wrap}@media (max-width:768px){.row{flex-direction:column;flex-wrap:nowrap}}.row.gutters>.row{margin-left:-2%}@media (max-width:768px){.row.gutters>.row{margin-left:0}}.row.gutters>.row>[class*=col-]{margin-left:2%}@media (max-width:768px){.row.gutters>.row>[class*=col-]{margin-left:0}}.row.around{justify-content:space-around}.row.between{justify-content:space-between}.row.auto .col{flex-grow:1}.col-1{width:8.3333333333%}.offset-1{margin-left:8.3333333333%}.col-2{width:16.6666666667%}.offset-2{margin-left:16.6666666667%}.col-3{width:25%}.offset-3{margin-left:25%}.col-4{width:33.3333333333%}.offset-4{margin-left:33.3333333333%}.col-5{width:41.6666666667%}.offset-5{margin-left:41.6666666667%}.col-6{width:50%}.offset-6{margin-left:50%}.col-7{width:58.3333333333%}.offset-7{
 margin-left:58.3333333333%}.col-8{width:66.6666666667%}.offset-8{margin-left:66.6666666667%}.col-9{width:75%}.offset-9{margin-left:75%}.col-10{width:83.3333333333%}.offset-10{margin-left:83.3333333333%}.col-11{width:91.6666666667%}.offset-11{margin-left:91.6666666667%}.col-12{width:100%}.offset-12{margin-left:100%}.gutters>.col-1{width:6.33333%}.gutters>.col-1:nth-child(n+13){margin-top:2%}.gutters>.offset-1{margin-left:10.33333%!important}.gutters>.col-2{width:14.66667%}.gutters>.col-2:nth-child(n+7){margin-top:2%}.gutters>.offset-2{margin-left:18.66667%!important}.gutters>.col-3{width:23%}.gutters>.col-3:nth-child(n+5){margin-top:2%}.gutters>.offset-3{margin-left:27%!important}.gutters>.col-4{width:31.33333%}.gutters>.col-4:nth-child(n+4){margin-top:2%}.gutters>.offset-4{margin-left:35.33333%!important}.gutters>.col-5{width:39.66667%}.gutters>.offset-5{margin-left:43.66667%!important}.gutters>.col-6{width:48%}.gutters>.col-6:nth-chil
 d(n+3){margin-top:2%}.gutters>.offset-6{margin-left:52%!important}.gutters>.col-7{width:56.33333%}.gutters>.offset-7{margin-left:60.33333%!important}.gutters>.col-8{width:64.66667%}.gutters>.offset-8{margin-left:68.66667%!important}.gutters>.col-9{width:73%}.gutters>.offset-9{margin-left:77%!important}.gutters>.col-10{width:81.33333%}.gutters>.offset-10{margin-left:85.33333%!important}.gutters>.col-11{width:89.66667%}.gutters>.offset-11{margin-left:93.66667%!important}.gutters>.col-12{width:98%}.gutters>.offset-12{margin-left:102%!important}@media (max-width:768px){[class*=" offset-"],[class^=offset-]{margin-left:0}}.first{order:-1}.last{order:1}@media (max-width:768px){.row [class*=col-]{margin-left:0;width:100%}.row.gutters [class*=col-]{margin-bottom:16px}.first-sm{order:-1}.last-sm{order:1}}.gutters .column.push-left,.push-left{margin-right:auto}.gutters .column.push-right,.push-right{margin-left:auto}.gutters .column.push-center,
 .push-center{margin-left:auto;margin-right:auto}.gutters .column.push-middle,.push-middle{margin-top:auto;margin-bottom:auto}.push-bottom{margin-top:auto}@media (max-width:768px){.gutters .column.push-left-sm,.push-left-sm{margin-left:0}.gutters .column.push-center-sm,.push-center-sm{margin-left:auto;margin-right:auto}.push-top-sm{margin-top:0}}.align-middle{align-items:center}.align-right{justify-content:flex-end}.align-center{justify-content:center}@media (max-width:768px){.align-left-sm{justify-content:flex-start}}.float-right{float:right}.float-left{float:left}@media (max-width:768px){.float-left,.float-right{float:none}}.fixed{position:fixed;top:0;left:0;z-index:100;width:100%}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;he
 ight:0}[hidden],template{display:none}a{background-color:transparent}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webki
 t-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}optgroup{font-weight:700}table{border-spacing:0}td,th{padding:0}p{margin:1rem 0}cite,dfn,em,i{font-style:italic}blockquote{margin:0 1.5rem}address{margin:0 0 1.5rem}pre{background:#eee;font-family:Courier\ 10 Pitch,Courier,monospace;font-size:.9375rem;line-height:1.6;margin-bottom:1.6rem;max-width:100%;overflow:auto;padding:1.6rem}code,kbd,tt,var{font-family:Monaco,Consolas,Andale Mono,DejaVu Sans Mono,monospace;font-size:.9375rem}abbr,acronym{border-bottom:1px dotted #666;cursor:help}ins,mark{background:#fff9c0;text-decoration:none}big{font-size:125%}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{background:#fff}blockquote,q{quotes:"" ""}blockquote:af
 ter,blockquote:before,q:after,q:before{content:""}blockquote{border-left:2px solid #767676;color:#767676;margin:1rem 0;padding-left:.8rem}blockquote cite{font-size:.8rem}figure{margin:0}hr{background-color:#eee;border:0;height:2px;margin:5rem auto}img{height:auto;max-width:100%}h1,h2,h3,h4,h5,h6{font-family:Open Sans,sans-serif;clear:both;line-height:1.5;margin:2rem 0 1rem}.h1,h1{font-size:2.44140625rem}.h1,.h2,h1,h2{font-weight:300}.h2,h2{font-size:1.953125rem}.h3,h3{font-size:1.5625rem;font-weight:400}.h4,h4{font-size:1.25rem;color:#32373c;font-weight:600;padding:0}.h5,h5{font-size:1rem;letter-spacing:.01rem}.h5,.h6,h5,h6{font-weight:600;text-transform:uppercase}.h6,h6{font-size:.8rem;letter-spacing:.8px}a{color:#0073aa;text-decoration:none}a:active,a:focus,a:hover{text-decoration:underline}a:focus{outline:thin dotted}a:active,a:hover{outline:0}li>a,p a{text-decoration:underline}li>a:hover,p a:hover{color:#d54e21}ol,ul{margin:0 0 1.5em 1.5em;padding:0}ul{list-style
 :square}ol{list-style:decimal}ol.unmarked-list,ul.unmarked-list{list-style:none;padding-left:0}li>ol,li>ul{margin-bottom:0}dt{font-weight:700}dd{margin:0 1.5em 1.5em}table{border:1px solid #eee;border-collapse:collapse;font-size:.8rem;margin:0 0 1rem;padding:0;width:100%}table thead{background:#32373c;color:#fff}table td,table th{border:1px solid #eee;font-weight:400;margin:0;padding:.4rem;text-align:left;vertical-align:top}table tbody tr:nth-child(2n){background:#f7f7f7}html{font-size:100%}body,button,input,select,textarea{color:#32373c;font-family:Open Sans,sans-serif;font-size:100%;line-height:1.5}@media screen and (min-width:737px){html{font-size:1.125rem}}.custom-select{display:inline-block;box-sizing:border-box;padding:.5rem 2rem .5rem .8rem;width:auto;font-size:1em;line-height:1.3;border:1px solid #6c7782;box-shadow:none;border-radius:.5em;-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:transparent;background-image:url('data:image/svg+xml;c
 harset=US-ASCII,%3Csvg width="14" height="8" xmlns="http://www.w3.org/2000/svg"%3E%3Cpath d="M2 0L7 5L12 0L14 1L7 8L0 1L2 0Z" fill="%23555D66"/%3E%3C/svg%3E%0A');background-repeat:no-repeat;background-position:right .7em top 50%;background-size:.65em auto}.custom-select::-ms-expand{display:none}.custom-select:focus{box-shadow:0 0 1px 3px rgba(59,153,252,.7);box-shadow:0 0 0 3px -moz-mac-focusring;color:#222;outline:none}.custom-select option{font-weight:400}html{font-size:1rem}@media screen and (min-width:737px){html{font-size:1rem}}.screen-reader-text{clip:rect(1px,1px,1px,1px);height:1px;overflow:hidden;position:absolute!important;width:1px}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;color:#21759b;display:block;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-in
 dex:100000}.site-content[tabindex="-1"]:focus{outline:0}.no-js .hide-if-no-js{display:none}.alignleft{display:inline;float:left;margin-right:1.5em}.alignright{display:inline;float:right;margin-left:1.5em}.aligncenter{clear:both;display:block;margin-left:auto;margin-right:auto}@media screen and (max-width:480px){.alignleft,.alignright{display:block;float:none;margin-left:auto;margin-right:auto}}.button,.button-primary,.button-secondary,.plugin-upload-form .button-primary{border:1px solid;border-radius:3px;box-sizing:border-box;cursor:pointer;display:inline-block;font-size:.8rem;height:1.5625rem;line-height:1;margin:0;padding:0 .8rem;text-decoration:none;white-space:nowrap;-webkit-appearance:none}button::-moz-focus-inner,input[type=button]::-moz-focus-inner,input[type=reset]::-moz-focus-inner,input[type=submit]::-moz-focus-inner{border:0;padding:0}.button-group.button-xl .button,.button.button-xl{font-size:1rem;height:2.44140625rem;line-height:1;padding:0 1.5rem}.button-grou
 p.button-large .button,.button.button-large{height:1.953125rem;line-height:1;padding:0 1rem}.button-group.button-small .button,.button.button-small{font-size:.64rem;height:1.25rem;line-height:1;padding:0 .5rem}a.button,a.button-primary,a.button-secondary{line-height:1.5625rem}.button-group.button-large a.button,a.button.button-large{line-height:1.953125rem}.button-group.button-xl a.button,a.button.button-xl{line-height:2.44140625rem}.button-group.button-small a.button,a.button.button-small{line-height:1.25rem}.button:active,.button:focus{outline:none}.button.hidden{display:none}input[type=reset],input[type=reset]:active,input[type=reset]:focus,input[type=reset]:hover{background:none;border:none;box-shadow:none;padding:0 2px 1px;width:auto}.button,.button-secondary,.button:visited{background:#f7f7f7;border-color:#ccc;box-shadow:0 1px 0 #ccc;color:#555;vertical-align:top}p .button{vertical-align:baseline}.button-secondary:focus,.button-secondary:hover,.button.focus,.button.hover,.butt
 on:focus,.button:hover{background:#fafafa;border-color:#999;color:#23282d}.button-link:focus,.button-secondary:focus,.button.focus,.button:focus{border-color:#5b9dd9;box-shadow:0 0 3px rgba(0,115,170,.8)}.button-secondary:active,.button.active,.button.active:hover,.button:active{background:#eee;border-color:#999;box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5);transform:translateY(1px)}.button.active:focus{border-color:#5b9dd9;box-shadow:inset 0 2px 5px -3px rgba(0,0,0,.5),0 0 3px rgba(0,115,170,.8)}.button-disabled,.button-secondary.disabled,.button-secondary:disabled,.button-secondary[disabled],.button.disabled,.button:disabled,.button[disabled]{background:#f7f7f7!important;border-color:#ddd!important;box-shadow:none!important;color:#a0a5aa!important;cursor:default;text-shadow:0 1px 0 #fff!important;transform:none!important}.button-link,input[type=submit].button-link{background:none;border:0;border-radius:0;box-shadow:none;cursor:pointer;margin:0;outline:none;padding:0}.button-link:
 focus{outline:1px solid #5b9dd9}.button-primary,.download-button,.plugin-upload-form .button-primary{text-decoration:none;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799}.button-primary,.button-primary:visited,.download-button,.download-button:visited,.plugin-upload-form .button-primary,.plugin-upload-form .button-primary:visited{background:#0085ba;border-color:#0073aa #006799 #006799;box-shadow:0 1px 0 #006799;color:#fff}.button-primary.focus,.button-primary.hover,.button-primary:focus,.button-primary:hover,.download-button.focus,.download-button.hover,.download-button:focus,.download-button:hover,.plugin-upload-form .button-primary.focus,.plugin-upload-form .button-primary.hover,.plugin-upload-form .button-primary:focus,.plugin-upload-form .button-primary:hover{background:#008ec2;border-color:#006799;box-shadow:0 1px 0 #006799;color:#fff}.button-primary.focus,.button-primary:focus,.download-button.focus,.download-button:focus,.plugin-upload-fo
 rm .button-primary.focus,.plugin-upload-form .button-primary:focus{box-shadow:0 1px 0 #0073aa,0 0 2px 1px #33b3db}.button-primary.active,.button-primary.active:focus,.button-primary.active:hover,.button-primary:active,.download-button.active,.download-button.active:focus,.download-button.active:hover,.download-button:active,.plugin-upload-form .button-primary.active,.plugin-upload-form .button-primary.active:focus,.plugin-upload-form .button-primary.active:hover,.plugin-upload-form .button-primary:active{background:#0073aa;border-color:#006799;box-shadow:inset 0 2px 0 #006799;vertical-align:top}.button-primary.disabled,.button-primary:disabled,.button-primary[disabled],.download-button.disabled,.download-button:disabled,.download-button[disabled],.plugin-upload-form .button-primary.disabled,.plugin-upload-form .button-primary:disabled,.plugin-upload-form .button-primary[disabled]{background:#008ec2!important;border-color:#007cb2!important;box-shadow:none!important;color:#66c6e4!impo
 rtant;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.button-primary.button.button-hero,.download-button.button.button-hero,.plugin-upload-form .button-primary.button.button-hero{box-shadow:0 2px 0 #006799}.button-primary.button.button-hero.active,.button-primary.button.button-hero.active:focus,.button-primary.button.button-hero.active:hover,.button-primary.button.button-hero:active,.download-button.button.button-hero.active,.download-button.button.button-hero.active:focus,.download-button.button.button-hero.active:hover,.download-button.button.button-hero:active,.plugin-upload-form .button-primary.button.button-hero.active,.plugin-upload-form .button-primary.button.button-hero.active:focus,.plugin-upload-form .button-primary.button.button-hero.active:hover,.plugin-upload-form .button-primary.button.button-hero:active{box-shadow:inset 0 3px 0 #006799}.button-primary-disabled{background:#008ec2!important;border-color:#007cb2!important;box-shadow:none!important;color:#66
 c6e4!important;cursor:default;text-shadow:0 -1px 0 rgba(0,0,0,.1)!important}.button-group{display:inline-block;font-size:0;position:relative;vertical-align:middle;white-space:nowrap}.button-group>.button{border-radius:0;display:inline-block;margin-right:-1px;z-index:10}.button-group>.button-primary{z-index:100}.button-group>.button:hover{z-index:20}.button-group>.button:first-child{border-radius:3px 0 0 3px}.button-group>.button:last-child{border-radius:0 3px 3px 0}.button-group>.button:focus{position:relative;z-index:1}@media screen and (max-width:737px){.button,.button.button-large,.button.button-small,.plugin-upload-form .button-primary{font-size:14px;height:auto;line-height:normal;margin-bottom:4px;padding:6px 14px;vertical-align:middle}}.clear:after,.clear:before,.comment-content:after,.comment-content:before,.entry-content:after,.entry-content:before,.home-below:after,.home-below:before,.site-content:after,.site-content:before,.site-footer:after,.site-footer:
 before,.site-header:after,.site-header:before{content:"";display:table;table-layout:fixed}.clear:after,.comment-content:after,.entry-content:after,.home-below:after,.site-content:after,.site-footer:after,.site-header:after{clear:both}p.subheading{color:#82878c;font-weight:300;margin:-.4rem auto 2rem;text-align:center}p.intro,p.subheading{font-size:1.25rem}p.aside{font-size:.8rem}p.note{font-size:.64rem;letter-spacing:.01rem;max-width:18.1898940355rem}input,textarea{box-sizing:border-box}input[type=checkbox],input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=radio],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{background-color:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);color:#32373c;outline:none;transition:border-color .05s ease-in-out}input[type=checkbox]:foc
 us,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=radio]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#5b9dd9;box-shadow:0 0 2px rgba(30,140,190,.8)}input[type=email],input[type=url]{direction:ltr}input[type=number]{height:28px;line-height:inherit}input[type=checkbox],input[type=radio]{background:#fff;border:1px solid #b4b9be;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);clear:none;color:#555;cursor:pointer;display:inline-block;height:16px;line-height:0;margin:-4px 4px 0 0;min-width:16px;outline:0;padding:0!important;text-align:center;transition:border-color .05s ease-in-out;vertical-align:middle;width:16px;-webkit-appearance:none}input[type=checkbox]:checked:before,input[type=radi
 o]:checked:before{display:inline-block;float:left;font:normal 21px/1 dashicons;vertical-align:middle;width:16px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}input[type=checkbox]:checked:before{color:#1e8cbe;content:"";margin:-3px 0 0 -4px}input[type=radio]{border-radius:50%;line-height:10px;margin-right:4px}input[type=radio]:checked+label:before{color:#82878c}input[type=radio]:checked:before{background-color:#1e8cbe;border-radius:50px;content:"•";font-size:24px;height:6px;line-height:16px;margin:4px;text-indent:-9999px;width:6px}input[type=reset]:active,input[type=reset]:hover{color:#00a0d2}input[type=search]{-webkit-appearance:te
 xtfield}input[type=search]::-webkit-search-decoration{display:none}button,input,select,textarea{font-family:inherit;font-size:inherit;font-weight:inherit}input,select,textarea{border-radius:0;font-size:14px;padding:3px 5px}textarea{line-height:1.4;overflow:auto;padding:2px 6px;resize:vertical}textarea.code{line-height:1.4;padding:4px 6px 1px}label{cursor:pointer;vertical-align:middle}input,select{margin:1px;padding:3px 5px}input.code{padding-top:6px}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}.wp-core-ui :-moz-placeholder,:-moz-placeholder{color:#a9a9a9}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:hsla(0,0%,100%,.5);border-color:hsla(0,0%,87.1%,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:none;box-shadow:none}input.large-text,textare
 a.large-text{width:99%}input.regular-text{width:25em}input.small-text{padding:1px 6px;width:50px}input[type=number].small-text{width:65px}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=email],input[type=number],input[type=password],input[type=search],input[type=text]{-webkit-appearance:none;padding:6px 10px}input[type=number]{height:40px}input.code{padding-bottom:5px;padding-top:10px}input[type=checkbox]{-webkit-appearance:none;padding:10px}input[type=checkbox]:checked:before{font:normal 30px/1 dashicons;margin:-3px -5px}input[type=checkbox],input[type=radio]{height:25px;width:25px}input[type=radio]:checked:before{vertical-align:middle;width:9px;height:9px;margin:7px;line-height:16px}input,textarea{font-size:16px}input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:55px;display:inline;padding:3px 6
 px;margin:0 3px}input.regular-text{width:100%}label{font-size:14px}fieldset label{display:block}}a.button:active,a.button:focus,a.button:hover{text-decoration:none}.notice{background:#fff;border-left:4px solid #fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:1em 0;padding:1px 12px}.notice p{font-size:.8rem;margin:.5em 0;padding:2px}.notice.notice-alt{box-shadow:none}.notice.notice-large{padding:10px 20px}.notice.notice-success{border-left-color:#46b450}.notice.notice-success.notice-alt{background-color:#ecf7ed}.notice.notice-warning{border-left-color:#ffb900}.notice.notice-warning.notice-alt{background-color:#fff8e5}.notice.notice-error{border-left-color:#dc3232}.notice.notice-error.notice-alt{background-color:#fbeaea}.notice.notice-info{border-left-color:#00a0d2}.notice.notice-info.notice-alt{background-color:#e5f5fa}.error-404 .page-content,.error-404 .page-title{text-align:center}.error-404 .page-content .logo-swing{height:10rem;margin:6rem auto;position:relative;text-align:cent
 er;width:10rem}.error-404 .page-content .logo-swing .wp-logo{left:0;max-width:none;position:absolute;top:0;width:10rem}@keyframes hinge{10%{width:180px;height:180px;transform:rotate(0deg)}15%{width:185px;height:185px;transform:rotate(0deg)}20%{width:180px;height:180px;transform:rotate(5deg)}40%{transform-origin:top left;animation-timing-function:ease-in-out}60%{transform:rotate(40deg);transform-origin:top left;animation-timing-function:ease-in-out}40%,80%{transform:rotate(60deg);transform-origin:top left;animation-timing-function:ease-in-out;opacity:1}to{transform:translate3d(0,700px,0);opacity:0}}.hinge{animation-duration:2s;animation-name:hinge}.comments-area{margin-top:5em}.comments-area>:last-child{margin-bottom:0}.comments-area .comment-list+.comment-respond{border-top:1px solid #eaeaea}.comments-area .comment-list+.comment-respond,.comments-area .comment-navigation+.comment-respond{padding-top:1.6em}.comments-area .comments-title{margin-bottom:1.3333em}.comments-area .comme
 nt-list{list-style:none;margin:0}.comments-area .comment-list .pingback,.comments-area .comment-list .trackback,.comments-area .comment-list article{border-top:1px solid #eaeaea;padding:1.6em 0}.comments-area .comment-list article:not(:only-child){padding-bottom:0}.comments-area .comment-list article+.comment-respond{padding-bottom:1.6em}.comments-area .comment-list .children{list-style:none;margin:0}.comments-area .comment-list .children>li{padding-left:.8em}.comments-area .comment-list .alt{background:none}.comments-area .comment-author{color:#999;margin-bottom:.4em}.comments-area .comment-author .avatar{float:left;height:24px;margin-right:.8em;width:24px}.comments-area .comment-metadata,.comments-area .pingback .edit-link{color:#999;line-height:1.5}.comments-area .comment-metadata a,.comments-area .pingback .edit-link a{color:#777}.comments-area .comment-metadata{font-size:.8rem;margin-bottom:1.6em}.comments-area .comment-metadata .edit-link,.comments-area .pingback .edit-link
 {margin-left:1em}.comments-area .pingback .edit-link:before{top:5px}.comments-area .comment-content ol,.comments-area .comment-content ul{margin:0 0 1.6em 1.3333em}.comments-area .comment-content>:last-child,.comments-area .comment-content li>ol,.comments-area .comment-content li>ul{margin-bottom:0}.comments-area .comment-content .reply{font-size:12px}.comments-area .comment-content .reply a{border:1px solid #eaeaea;color:#707070;display:inline-block;font-weight:700;line-height:1;margin-top:2em;padding:.4167em .8333em;text-transform:uppercase}.comments-area .comment-content .reply a:focus,.comments-area .comment-content .reply a:hover{border-color:#333;color:#333;outline:0}.comments-area .comment-reply-title a{font-weight:inherit}.comments-area .comment-form label{font-size:.8rem;font-weight:700;display:block;letter-spacing:.04em;line-height:1.5}.comments-area .comment-form input[type=email],.comments-area .comment-form input[type=text],.comments-area .comment-form input[ty
 pe=url],.comments-area .comment-form textarea{width:100%}.comments-area .comment-awaiting-moderation,.comments-area .comment-notes,.comments-area .form-allowed-tags,.comments-area .logged-in-as{font-size:1rem;line-height:1.5;margin-bottom:2em}.comments-area .no-comments{border-top:1px solid #eaeaea;color:#999;font-weight:700;padding-top:1.6em}.comments-area .comment-navigation+.no-comments{border-top:0}.comments-area .form-allowed-tags code{font-family:Inconsolata,monospace}.comments-area .form-submit{margin-bottom:0}.comments-area .required{color:#c0392b}.entry-content{hyphens:auto;word-wrap:break-word}.entry-content>p:first-child{margin-top:0}.entry-content [class*=col-]~h1,.entry-content [class*=col-]~h2,.entry-content [class*=col-]~h3,.entry-content [class*=col-]~h4,.entry-content [class*=col-]~h5,.entry-content [class*=col-]~h6{clear:none}.entry-header{position:relative}.entry-header .sticky-post{color:#999;font-size:.8rem;font-style:italic;position:absolute;top:-.8rem}.entr
 y-meta{color:#999;font-size:.8rem;margin-bottom:1rem}.entry-meta a{color:#777}.entry-meta>span{margin-right:1rem}.entry-meta>span :last-of-type{margin:0}.entry-meta .byline,.entry-meta .updated:not(.published),.sticky .entry-meta .posted-on{display:none}.group-blog .entry-meta .byline,.single .entry-meta .byline{display:inline}.entry-summary{hyphens:auto;word-wrap:break-word}body:not(.single):not(.search) .site-main .post{margin-bottom:3.0517578125rem;max-width:40em}.gallery{margin-bottom:1.5rem}.gallery .gallery-item{display:inline-block;margin:0;text-align:center;vertical-align:top;width:100%}.gallery.gallery-columns-2 .gallery-item{max-width:50%}.gallery.gallery-columns-3 .gallery-item{max-width:33.33%}.gallery.gallery-columns-4 .gallery-item{max-width:25%}.gallery.gallery-columns-5 .gallery-item{max-width:20%}.gallery.gallery-columns-6 .gallery-item{max-width:16.66%}.gallery.gallery-columns-7 .gallery-item{max-width:14.28%}.gallery.gallery-columns-8 .gallery-item{max-width
 :12.5%}.gallery.gallery-columns-9 .gallery-item{max-width:11.11%}.gallery .gallery-caption{display:block}.main-navigation{background:#0073aa;clear:both;left:0;position:absolute;top:60px;width:100%}.main-navigation ul{display:none;list-style:none;margin:0;padding-left:0}.main-navigation ul ul{box-shadow:0 3px 3px rgba(0,0,0,.2);float:left;left:-999em;position:absolute;top:1.5em;z-index:99999}.main-navigation ul ul ul{left:-999em;top:0}.main-navigation ul ul li.focus>ul,.main-navigation ul ul li:hover>ul{left:100%}.main-navigation ul ul a{width:200px}.main-navigation ul li.focus>ul,.main-navigation ul li:hover>ul{left:auto}.main-navigation li{border-top:1px solid hsla(0,0%,100%,.2);padding:1rem}.main-navigation a{color:hsla(0,0%,100%,.8);display:block;font-size:.8rem;text-decoration:none}.main-navigation a.active,.main-navigation a:hover{color:#fff}@media screen and (min-width:737px){.main-navigation a.active{border-bottom:1px solid}}.main-navigation.toggled{z-index:1}.mai
 n-navigation.toggled ul{display:block}.menu-toggle{background:transparent;border:none;color:#fff;height:3.5rem;position:absolute;right:1rem;top:-58px;width:3.5rem}.toggled .menu-toggle:before{content:""}@media screen and (min-width:737px){.menu-toggle{display:none}.main-navigation{float:right;position:static;width:auto}.main-navigation.toggled{padding:1px 0}.main-navigation ul{display:inline-block;font-size:0}.main-navigation ul li{border:0;display:inline-block;font-size:1rem;margin-right:1rem;padding:0}.main-navigation ul li:last-of-type{margin-right:0}}.comment-content .wp-smiley,.entry-content .wp-smiley,.page-content .wp-smiley{border:none;margin-bottom:0;margin-top:0;padding:0}embed,iframe,object{max-width:100%}body.page .gutters .col-12{width:100%}body.page .entry-header{background:#0073aa;padding:1rem 0}body.page .entry-header .entry-title{color:#fff;font-size:1.5625rem;font-weight:300;line-height:1;margin:0 auto;padding:0 1.5625rem}body.page .entry-header.home{p
 adding:1.5625rem 1.143rem;text-align:center}@media screen and (min-width:737px){body.page .site-header+.site-main .entry-title{padding:initial}}body.page .entry-content,body.page .entry-footer{margin:0 auto;max-width:960px;padding:3.0517578125rem 1.5625rem}.post-navigation{margin:5em auto;padding:0}.post-navigation a{border-bottom:1px solid #eaeaea;color:#444;display:block;font-weight:600;padding:11px 0 12px;text-transform:none;width:100%}.post-navigation a:hover{color:#21759b}.post-navigation .nav-links{border-top:1px solid #eaeaea;hyphens:auto;word-wrap:break-word}.post-navigation .meta-nav{color:#777;display:block;font-size:13px;line-height:2;text-transform:uppercase}.post-navigation .nav-next{text-align:right}.pagination .nav-links{text-align:center}.pagination .nav-links .page-numbers{background-color:#f9f9f9;cursor:hand;display:inline-block;min-width:2em;padding:8px}.pagination .nav-links .page-numbers.dots,.pagination .nav-links .page-numbers.next,.pagination .nav-links .page
 -numbers.prev{background:none;font-size:.9em;width:auto}.pagination .nav-links .page-numbers.dots{cursor:inherit}@media screen and (max-width:737px){.pagination .nav-links .page-numbers.next,.pagination .nav-links .page-numbers.prev{font-size:0;min-width:0;padding:0}.pagination .nav-links .page-numbers.next:after,.pagination .nav-links .page-numbers.prev:before{background-color:#f9f9f9;display:inline-block;font-size:1rem;line-height:1.5;min-width:2em;padding:8px}.pagination .nav-links .page-numbers.prev:before{content:"‹"}.pagination .nav-links .page-numbers.next:after{content:"›"}}.pagination .nav-links span.page-numbers{background-color:#f7f7f7;font-weight:700}.search-form .search-field{line-height:normal;margin:0;padding:4px 5px;vertical-align:text-bottom}body.search .gutters .col-12{width:100%}body.search .site-main{margin:0 auto;max-width:960px;padding:0 1.5625rem 3.0517578125rem}.site-content{max-width:960px;padding:0 1.5625rem}@media screen and (min-wi
 dth:737px){.site-content{padding:0 10px 3.0517578125rem}}@media screen and (max-width:737px){.site-content .site-main{float:none;margin:0;width:auto}}.home .site-content,.page .site-content,.site-content.page{margin:auto;max-width:none;padding:0}.site-content .page-title{font-size:1.25rem;font-weight:400}.site-content .no-results{margin:0 auto 3.0517578125rem;max-width:40em;padding:0 2rem}.site-description{color:hsla(0,0%,100%,.8);font-size:1.25rem;font-weight:300;margin:-.4rem auto 2rem;text-align:center}.site-header{background:#0073aa;padding:1rem 0;position:relative}.site-header .site-branding{margin:0 auto;max-width:960px;padding:0 1.5625rem}@media screen and (min-width:737px){.site-header .site-branding{padding:0 10px}}.site-header.home{padding:1.5625rem 1.143rem;text-align:center}.site-title{display:inline-block;font-size:1.5625rem;font-weight:300;line-height:1;margin:0 2rem 0 0;max-width:none}.site-title a{color:#fff;font-weight:300}.site-title a:active,.site-title a:focus,.s
 ite-title a:hover{text-decoration:none}.site-header.home .site-title{display:inherit;font-size:3.8146972656rem;margin:2rem 0 1rem}.widget-area{font-size:.8rem}@media screen and (min-width:480px) and (max-width:768px){.widget-area{display:flex}.widget-area .widget{width:48%}}#wporg-footer{background-color:#f7f7f7;border-top:1px solid #dfdfdf;padding:22px 14px 65px}#wporg-footer,#wporg-footer .wrapper{clear:both;margin:0 auto;overflow:auto}#wporg-footer .wrapper{max-width:930px}#wporg-footer ul{float:left;margin-bottom:20px;margin-left:24px;overflow:auto;padding-left:0;width:135px}@media screen and (min-width:960px){#wporg-footer ul:first-child{margin-left:0}}#wporg-footer ul li{color:#bbb;font-size:14px;list-style-type:none;margin-bottom:1px}#wporg-footer ul li a{text-decoration:none;text-decoration-skip-ink:none}#wporg-footer ul li a:hover{color:#0073aa;text-decoration:underline}#wporg-footer .cip{clear:both;color:#ccc;float:none;font-size:.8rem;letter-spacing:.3em;margin:35px auto 
 0;text-align:center;text-transform:uppercase}#wporg-footer .cip.cip-image{background:url(//s.w.org/style/images/codeispoetry.png?1=) 50% no-repeat;background-size:190px 15px;height:15px;text-indent:-9999px;width:190px}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:1.5dppx),only screen and (min-resolution:144dpi){#wporg-footer .cip.cip-image{background-image:url(//s.w.org/style/images/codeispoetry-2x.png?1=)}}@media screen and (min-width:561px) and (max-width:959px){#wporg-footer .wrapper{max-width:600px}#wporg-footer ul{margin-left:2%;width:32%}#wporg-footer ul:nth-child(3n+1){margin-left:0}#wporg-footer ul:nth-child(4n){clear:both}}@media screen and (max-width:560px){#wporg-footer .wrapper{max-width:360px}#wporg-footer ul{margin-left:4%;width:48%}#wporg-footer ul:nth-child(odd){margin-left:0;clear:both}}#wporg-header{background:#23282d;height:140px;position:relative;text-align:center;width:100%}#wporg-header .wrapper{margin:0 auto;max-wi
 dth:960px}#wporg-header h1{display:inline-block;margin:auto;width:303px}#wporg-header h1 a{background:url(//s.w.org/style/images/wporg-logo.svg?3=) 0 no-repeat;background-size:290px 46px;display:block;height:88px;text-indent:-9999px}#wporg-header h2.rosetta{clear:none;color:#dfdfdf;font-family:Georgia,Times New Roman,serif;font-size:30px;margin:0 0 0 60px}#wporg-header h2.rosetta a{border-bottom:none;color:#dfdfdf;display:block;height:52px;line-height:22px;padding:0}#wporg-header h2.rosetta a:hover{text-decoration:none}#wporg-header #wporg-header-menu{background:#23282d;left:-75%;list-style:none;margin:0;max-width:75%;min-width:200px;position:absolute;text-align:left;top:100%;transition:left .3s;z-index:100000}#wporg-header #wporg-header-menu.toggled{left:0}#wporg-header ul li{list-style-type:none;position:relative}#wporg-header ul li a{color:#eee;display:block;font-family:Open Sans,Helvetica,Arial,Liberation Sans,sans-serif;font-size:13px;font-weight:600;height:34px;line-height:34p
 x;margin:0 4px;padding:10px 30px;text-decoration:none}#wporg-header ul li a.subcurrent{font-weight:700}@media (max-width:768px){#wporg-header ul li a{height:auto}}#wporg-header ul li.current-menu-item a,#wporg-header ul li.current_page_parent a,#wporg-header ul li a.current,#wporg-header ul li a:hover{color:#00a0d2}#wporg-header ul li#download,#wporg-header ul li.download{float:right;height:34px;margin-right:14px;overflow:hidden;padding:0 0 34px}@media screen and (max-width:767px){#wporg-header ul li#download,#wporg-header ul li.download{display:block;float:none;margin:10px 20px 20px;padding-bottom:0;height:auto}#wporg-header ul li#download a,#wporg-header ul li.download a{padding:4px 10px;text-align:center}}#wporg-header ul li#download a,#wporg-header ul li.download a{margin:0;padding:0 16px}#wporg-header ul li#download a:hover,#wporg-header ul li.download a:hover{color:#eee}#wporg-header ul li#download.current,#wporg-header ul li#download.current-menu-item,#wporg-header ul li#down
 load .uparrow,#wporg-header ul li.download.current,#wporg-header ul li.download.current-menu-item,#wporg-header ul li.download .uparrow{display:none}#wporg-header ul li .nav-submenu{clip:rect(1px,1px,1px,1px);height:1px;left:-2px;margin:0;overflow:hidden;padding:0;position:absolute;width:1px;z-index:99999}#wporg-header ul li .nav-submenu li a{display:inline-block;height:24px;line-height:24px;margin:0;white-space:nowrap}@media screen and (min-width:768px){#wporg-header #head-search{float:right;margin-right:14px;padding-top:30px}}#wporg-header #head-search form{border-bottom:1px solid #3f3f3f;display:inline-block;margin-left:60px;width:288px}#wporg-header #head-search form input.text{background:#191e23;border:0;border-radius:0;box-sizing:content-box;color:#b4b9be;float:left;font-family:Open Sans,sans-serif;font-size:12px;height:24px;margin:0;outline:none;padding:3px;vertical-align:top;width:256px}#wporg-header #head-search form input.text::-moz-placeholder{color:#eee}@media screen and
  (max-width:480px){#wporg-header #head-search form input.text{width:216px}}#wporg-header #head-search form .button{background:#191e23 url(//s.w.org/wp-includes/images/admin-bar-sprite.png?d=20120831) no-repeat 2px 5px;border:none;border-radius:0;box-shadow:none;float:left;height:30px;margin:0;padding:0;text-shadow:none!important;width:26px}@media screen and (max-width:480px){#wporg-header #head-search form{width:248px}}@media screen and (min-width:480px){#wporg-header #head-search form{margin-left:0}}@media screen and (min-width:768px){#wporg-header{height:120px;text-align:inherit}#wporg-header h1{float:left;padding-left:10px}#wporg-header h2.rosetta{float:left;margin-left:0;padding:36px 27px 0}#wporg-header #headline h2{text-rendering:optimizeLegibility}#wporg-header #wporg-header-menu{float:left;height:46px;list-style:none;margin:-15px 0 0;max-width:inherit;min-width:0;padding:0;position:static;width:100%}#wporg-header ul li{float:left;position:relative}#wporg-header ul li a{heigh
 t:46px;padding:0 6px}#wporg-header ul li a.current~.uparrow{border-bottom:9px solid #f7f7f7;border-left:9px solid transparent;border-right:9px solid transparent;height:0;margin:-8px auto 0;width:0}#wporg-header ul li.current-menu-item:after,#wporg-header ul li.current_page_parent:after{border-bottom:9px solid #f7f7f7;border-left:9px solid transparent;border-right:9px solid transparent;content:"";height:0;left:50%;margin:-8px 0 0 -9px;position:absolute;width:0}#wporg-header ul li .nav-submenu:hover~.uparrow,#wporg-header ul li:hover .nav-submenu~.uparrow{border-bottom:9px solid #32373c;border-left:9px solid transparent;border-right:9px solid transparent;height:0;margin:-10px auto 0;width:0}#wporg-header ul li .nav-submenu{background:#32373c;border:1px solid #32373c;border-top:0;margin-top:-1px;min-width:0}#wporg-header ul li .nav-submenu li{float:none}#wporg-header ul li .nav-submenu li a{height:34px;line-height:34px}#wporg-header .nav-menu .focus>ul,#wporg-header .nav-m
 enu ul li:hover>ul,#wporg-header ul.nav-menu .focus>ul,#wporg-header ul.nav-menu li:hover>ul{clip:inherit;height:inherit;overflow:inherit;width:inherit}#wporg-header ul li.current-menu-item:after,#wporg-header ul li.current_page_parent:after,#wporg-header ul li a.current~.uparrow{border-bottom-color:#0073aa}}.page-download #wporg-header #download,.page-parent-download #wporg-header #download{display:none}#mobile-menu-button{background:none;border:none;box-shadow:none;display:block;float:left;font-family:dashicons;font-size:16px;font-style:normal;font-weight:400;left:10px;line-height:1;padding:1px;position:absolute;text-align:center;text-decoration:inherit;text-shadow:none;top:75px;transition:color .1s ease-in;vertical-align:top;-webkit-font-smoothing:antialiased}#mobile-menu-button:before{border:none;box-sizing:border-box;color:#888;content:"";display:inline-block;float:left;font:normal 50px/1 Dashicons;margin:0;outline:none;padding:3px;text-decoration:none;ver
 tical-align:middle;-webkit-font-smoothing:antialiased}@media screen and (min-width:768px){#mobile-menu-button{display:none}}#download-mobile{background:#f7f7f7;border-bottom:1px solid #ddd}#download-mobile .wrapper{padding:20px 0;text-align:center}#download-mobile span.download-ready{font-size:1.6em;margin:0 .25em}#download-mobile a.download-button{font-size:1.6em;height:inherit;margin:10px .25em;padding:10px 15px}.category-context__bar{margin:0 1.5rem;background:#edeff0;border-radius:2px;font-size:.8125rem;overflow:auto;transition:all .1s ease-out;transition-delay:.1s}.category-context__bar>div{display:flex;align-items:center;justify-content:space-between}@media only screen and (min-width:782px){.category-context__bar{margin:0 1.5rem}}@media only screen and (min-width:960px){.category-context__bar{margin:0 auto;max-width:960px}}.category-context__bar ul{margin:0;padding:0;display:flex;justify-content:space-between}.category-context__bar ul li{list-style:none;font-size:.8125rem}.
 category-context__bar ul li a{display:block;padding:1.125rem .75rem;text-decoration:none}.category-context__bar ul li:last-child a{padding-right:1.5rem}.category-context__bar__copy{margin:0;padding:1.125rem 1.5rem;font-size:.8125rem;font-weight:400}.category-context__bar__title{margin:0;padding-right:1.5rem;color:#555d66;font-size:.75rem;font-weight:400;text-transform:uppercase}.category-context__bar__links{display:flex;align-items:center}@media only screen and (max-width:782px){.category-context__bar__links{display:none}}.category-context__bar--is-hidden{height:0;overflow:hidden}.category-menu{margin:0;padding:0;position:relative;background:linear-gradient(180deg,hsla(0,0%,100%,0) 94%,#0073aa 0);background-repeat:no-repeat;background-size:0;background-position-x:0;transition:all 75ms ease-out;min-height:45px}.category-menu li{display:inline-block;margin:0;list-style:none}.category-menu a{display:block;padding:.75rem;color:#40464d;font-size:.875rem;text-decoration:none}.category-men
 u a:active,.category-menu a:focus,.category-menu a:hover,li .category-menu--is-active{color:#000}.category-menu__mobile{padding:0!important;border-top:none!important}.category-menu__mobile ul{margin:0;padding:0;background:#23282d}.category-menu__mobile li{list-style:none;border-top:1px solid #32373c}.category-menu__mobile li a{display:block;padding:1rem 1.5rem;font-size:.875rem;text-decoration:none;color:#ccd0d4}.category-menu__mobile>.components-panel__body-title{margin:0!important}.category-menu__mobile>.components-panel__body-title>button{padding:1.5rem}.category-menu--is-loading{height:24px;position:relative}.category-menu--is-loading:after{content:"";position:absolute;background:#f3f4f5;border-radius:4px;width:80%;height:24px;left:0;top:calc(50% - 12px);transition:none}.category-search{display:flex;align-items:center;background:#fff;border:1px solid #6c7782;border-radius:2px}.category-search input[type=search]{flex-grow:1;margin:0;padding:.25rem .5rem;border:
 none;box-shadow:none;font-size:.8125rem}.category-search input[type=search]:focus{outline:1px auto #0073aa}.category-search__button{display:flex;background:transparent;border:none;color:#6c7782}.category-search__button:active{background:#d7dade}.category-search__button:focus{outline:1px auto #0073aa}.category-search--is-loading{display:block;height:24px;min-width:100%;background:#f3f4f5;border-radius:4px}@media only screen and (min-width:480px){.category-search--is-loading{width:224px!important;min-width:auto!important}}.pattern__copy-button{transition:all 75ms ease-in-out}.pattern__copy-button.is-small{font-size:.75rem;padding:.75rem;height:auto}.pattern__favorite-button{position:relative;font-size:.875rem;height:2.25rem;width:2.25rem;border-radius:2px;color:#606a74}.pattern__favorite-button svg{position:absolute;top:calc(50% - .75rem);left:calc(50% - .75rem);height:1.5rem;width:1.5rem;transition:all .15s ease-out}.pattern__favorite-button svg path{fill:#6c7782}.pattern__favorite-b
 utton .pattern__favorite-filled{opacity:0}.pattern__favorite-button:hover{color:#555d66;background:transparent}.pattern__favorite-button:hover svg path{fill:#555d66}.pattern__favorite-button:active{background:transparent;box-shadow:none;transform:none}.pattern__favorite-button.is-favorited{color:#555d66}.pattern__favorite-button.is-favorited svg path{fill:#d94f4f}.pattern__favorite-button.is-favorited .pattern__favorite-outline{opacity:0;transform:scale(2.8)}.pattern__favorite-button.is-favorited .pattern__favorite-filled{opacity:1}.pattern__favorite-button.is-favorited:hover .pattern__favorite-filled{animation:HeartBeat .9s infinite}@media (prefers-reduced-motion){.pattern__favorite-button.is-favorited:hover .pattern__favorite-filled{animation:none}}.pattern__favorite-button.has-label{padding:12px 18px 12px 38px;height:auto;width:auto}.pattern__favorite-button.has-label svg{top:calc(50% - 12px);left:9px}@keyframes HeartBeat{0%{transform:scale(1)}25%{transform:scale(1.2)}40%{transfo
 rm:scale(1)}60%{transform:scale(1.2)}to{transform:scale(1)}}.main-navigation{float:none;position:static;width:auto}.main-navigation a{font-size:.8125rem}.main-navigation.toggled div.menu{position:absolute;top:57px;right:0;width:100%;background:#0073aa}.menu-toggle{position:static;height:auto;width:auto;font-size:1.5625rem;overflow:hidden;-webkit-appearance:none}body.page .entry-header{background:none;padding:0}body.page .entry-header .entry-title{color:inherit;margin:2rem auto 1rem;max-width:960px}@media screen and (min-width:737px){body.page .entry-header .entry-title{padding:0 10px}}.pattern-grid-menu{margin:0 auto;max-width:960px;display:flex;flex-direction:column;justify-content:space-between;align-items:center}.pattern-grid-menu>:first-child,.pattern-grid-menu>:last-child{width:100%}.pattern-grid-menu>:last-child{margin:1.5rem;width:calc(100% - 3rem)}@media only screen and (min-width:782px){.pattern-grid-menu{margin:1.5rem;flex-direction:row}.pattern-grid-menu>:last
 -child{margin:0;width:auto}}@media only screen and (min-width:960px){.pattern-grid-menu{margin:1.5rem auto}}.pattern-grid{max-width:960px;margin:1.5rem}@media screen and (min-width:600px){.pattern-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1.5rem}.pattern-grid>*{align-self:baseline}}@media screen and (min-width:960px){.pattern-grid{margin-left:auto;margin-right:auto}}.pattern-grid__pattern{position:relative;margin:0 0 1.5rem;border:1px solid #d7dade;border-radius:2px;transition:all 75ms ease-in-out}@media screen and (min-width:600px){.pattern-grid__pattern{display:inline-block;margin:0}}.pattern-grid__pattern .pattern-grid__preview{overflow:hidden}.pattern-grid__pattern .pattern-grid__actions{position:absolute;right:0;bottom:0;left:0;display:flex;align-items:center;padding:.375rem;background:hsla(0,0%,100%,.8);backdrop-filter:blur(3px);opacity:0;transform:translateY(6px);transition:all 75ms ease-in-out}.pattern-grid__pattern .pattern-grid__act
 ions .pattern-grid__title{flex-grow:1;margin:0;padding:0 .375rem 0 .75rem;font-size:.75rem;pointer-events:none}.pattern-grid__pattern .pattern-grid__actions .pattern__copy-button,.pattern-grid__pattern .pattern-grid__actions .pattern__favorite-button{flex-shrink:0}.pattern-grid__pattern .pattern-grid__actions .button+.button{margin-left:.375rem}.pattern-grid__pattern:focus-within .pattern-grid__actions,.pattern-grid__pattern:hover .pattern-grid__actions{opacity:1;transform:translateY(0)}.pattern-preview__container{padding:2rem 0 0;background:#f3f4f5}.pattern-preview__viewport{position:relative;margin:0 auto;padding:0 20px;max-width:100vw;min-width:320px}.pattern-preview__viewport .pattern-preview__viewport-iframe{background:#fff;border:1px solid #e8eaeb;vertical-align:middle;max-width:100vw}.pattern-preview__viewport:focus-within .pattern-preview__resize-help{clip:auto;clip-path:none;height:auto;margin:initial;overflow:initial;width:auto;bottom:-1rem;left:20px;right:20px;padding:8px
  16px;background:#fff;border-radius:2px;border:1px solid #d7dade;text-align:center}.pattern-preview__drag-handle{position:absolute;top:0;bottom:0;width:20px}.pattern-preview__drag-handle.is-left{left:0}.pattern-preview__drag-handle.is-right{right:0}.pattern-preview__drag-handle-button{position:absolute;top:calc(50% - 50px);left:6px;padding:0;width:8px;height:100px;appearance:none;cursor:grab;outline:none;background:#7e8993;border-radius:99999px;border:none}.pattern-preview__drag-handle-button:hover{background:#6c7782}.pattern-preview__drag-handle-button:active{cursor:grabbing;background:#606a74}.pattern-preview__drag-handle-button:focus{box-shadow:0 1px 0 #0073aa,0 0 2px 1px #33b3db}body.single-wporg-pattern{box-sizing:border-box;font-size:14px;font-weight:400;line-height:1.2}body.single-wporg-pattern .site-content{margin:auto;max-width:none;padding:0}body.single-wporg-pattern .entry-header{max-width:960px;padding:1.5rem;margin-left:auto;margin-right:auto}@media only screen and (min
 -width:960px){body.single-wporg-pattern .entry-header{padding:1.5rem 0}}body.single-wporg-pattern .entry-header .entry-title{margin-top:0;line-height:1.2}body.single-wporg-pattern .pattern-actions{display:flex;align-items:stretch;flex-wrap:wrap}body.single-wporg-pattern .pattern-actions button+button{margin-left:2em}body.single-wporg-pattern .pattern-actions__notice{margin:1.5rem 0 0;height:auto;flex-basis:100%}body.single-wporg-pattern .pattern-actions__notice>*{display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;margin:0}body.single-wporg-pattern .pattern-actions__notice>* button{margin-top:.75rem}@media only screen and (min-width:600px){body.single-wporg-pattern .pattern-actions__notice>*{align-items:center;flex-direction:row}body.single-wporg-pattern .pattern-actions__notice>* button{margin-top:0}}body.single-wporg-pattern .pattern-actions__guide{max-width:384px;height:auto;max-height:none}body.single-wporg-pattern .pattern-actions
 __guide-content{padding:1.5rem;line-height:1.5}body.single-wporg-pattern .pattern-actions__guide-title{margin:0}body.single-wporg-pattern .pattern-actions__guide-shortcut{background:#edeff0;box-shadow:0 0 0 1px #ccd0d4;padding:1px;font-weight:600;min-width:20px;display:inline-block;text-align:center;border-radius:2px}body.single-wporg-pattern .entry-content{max-width:960px;margin-left:auto;margin-right:auto}body.single-wporg-pattern .pattern__meta{padding:2rem 0;background:#f3f4f5}body.single-wporg-pattern .pattern__meta>div{max-width:960px;margin-left:auto;margin-right:auto;display:flex;justify-content:space-between}body.single-wporg-pattern .pattern__meta .pattern-preview__report{text-align:right}.site-header:not(.home) .search-form{display:flex;align-items:center}.site-header:not(.home) .search-form>input{flex:1;border:0;border-radius:2px 0 0 2px;display:inline-block;font-size:12px;padding:5px 10px;position:relative;width:auto;height:100%}.site-header:not(.home) .search-for
 m button{margin:0;border-radius:0 2px 2px 0;padding:3px 12px;height:unset}.search-form--is-inline .search-form{display:flex;justify-content:space-between;background:#fff}.search-form--is-inline .search-form>label{flex:1}.search-form--is-inline .search-form input{padding:.5rem;background:transparent;border:none;box-shadow:none;width:100%;font-size:14px}@media only screen and (min-width:768px){.search-form--is-inline .search-form input{font-size:16px}}.search-form--is-inline .search-form button{background:transparent;margin-bottom:0;border:0;box-shadow:none;height:inherit;text-shadow:none;color:#32373c}.search-form--is-inline .search-form button:focus{-webkit-box-shadow:0 0 2px 1px #0073aa;box-shadow:0 0 2px 1px #0073aa}.search-form--is-centered .search-form{margin:0 auto}.search-form--is-constrained .search-form{max-width:36rem}.search-form--is-muted .search-form{border-color:#d7dade!important}.search-form--is-muted .search-form button,.search-form--is-muted .search-form input{bac
 kground:#f8f9f9;color:#7e8993}.search-form--has-medium-text .search-form input{font-size:14px}.search-form--has-border .search-form{border:1px solid #7e8993}.section-heading_link,.section-heading_title{margin-bottom:0}.section-heading_title{font-weight:300}.section-heading_title .archive-title-prefix{display:block;font-size:1rem}.section-heading_link{text-decoration:underline;font-weight:600;margin-top:1.5rem!important}@media only screen and (min-width:768px){.section-heading_link{margin-top:0!important}}.section-heading_description{margin:1rem 0 0}.section-heading_description :last-child{margin-bottom:0}.section-heading--with-space{padding-bottom:16px}.site-content{margin:0 auto;max-width:none;padding:0}body.home .site-header{padding:3.75rem 1rem;text-align:left}body.home .site-branding{display:grid;grid-template-rows:auto 1fr;grid-template-columns:1fr 22rem}body.home .site-branding>*{align-self:center}@media screen and (max-width:736px){body.home .site-branding{display:block}}b
 ody.home .site-title.site-title{grid-column-start:1;grid-row-start:1;margin-top:0;text-align:left;font-size:3rem;line-height:1.25}body.home .site-description{grid-column-start:1;grid-row-start:2;margin:0;font-size:1.25rem;line-height:1.6;text-align:left;color:#fff}body.home .site-callout{grid-column-start:2;grid-row-start:1;grid-row-end:span 2;margin-left:4rem;padding:1.125rem 1.5rem 1.5rem;font-size:.875rem;line-height:1.6;background:#fff;box-shadow:.75rem .75rem 0 rgba(0,0,0,.15)}body.home .site-callout h2{margin-top:0;font-size:1.125rem;line-height:1.25;font-weight:600}body.home .site-callout p:last-child{margin-bottom:0}@media screen and (max-width:736px){body.home .site-callout{margin:2rem auto 0;max-width:24rem}}body:not(.home) .site-branding{display:flex;align-items:center;justify-content:space-between;font-size:.8125rem;color:#fff}body:not(.home) .site-branding a{color:#fff}body:not(.home) .site-branding .sep{margin-left:.5rem;margin-right:.5rem}body:not(.home) .site-brandin
 g .is-current-page{font-weight:600}.site-title a{text-decoration:none}.site-title a:active,.site-title a:focus,.site-title a:hover{color:#fff}.has-wporg-blue-color{color:#1e8cbe}.has-wporg-blue-background-color{background-color:#1e8cbe}.has-wporg-purple-color{color:#826eb4}.has-wporg-purple-background-color{background-color:#826eb4}.has-wporg-white-color{color:#fff}.has-wporg-white-background-color{background-color:#fff}.home-page .shapes{position:relative;margin:0 auto}.home-page .shapes .parallelogram p:before{font-size:64px;height:64px;left:-16px;position:relative}.home-page .shapes .parallelogram{color:#fff;display:block;margin:0 auto;opacity:.9;padding:60px 40px;text-align:center;text-decoration:none}.home-page .shapes strong{display:block;font-size:28px;font-weight:300;padding-bottom:15px;padding-top:15px}.home-page .shapes p{color:#fff;font-size:16px;font-weight:300;margin:0}.home-page .shapes u{display:block;font-size:18px;padding-top:15px}@media only screen and (min-width:7
 68px){.home-page .shapes{height:400px}.home-page .shapes .parallelogram{width:50%;position:absolute;padding:50px 90px}}@media only screen and (min-width:960px){.home-page .shapes .parallelogram{-webkit-transform:skew(-15deg);-ms-transform:skew(-15deg);transform:skew(-15deg)}.home-page .shapes .parallelogram:before,.home-page .shapes p{-webkit-transform:skew(15deg);-ms-transform:skew(15deg);transform:skew(15deg)}}@media only screen and (min-width:1200px){.home-page .shapes{margin:0 -60px}}.terms{font-style:italic;font-size:14px}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsimagescopypastedemogif"></a>
<div class="binary"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx" style="display: block; padding: 0 10px">Index: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif
</span><span class="cx" style="display: block; padding: 0 10px">===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif        2021-04-26 04:01:47 UTC (rev 10923)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif 2021-04-26 17:12:15 UTC (rev 10924)
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/images/copy-paste-demo.gif
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:mime-type</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+application/octet-stream
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternsindexphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/index.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/index.php      2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/index.php        2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,7 +19,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        <main id="main" class="site-main" role="main">
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                <div id="pattern-grid__container">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         <div id="patterns__container">
</ins><span class="cx" style="display: block; padding: 0 10px">                         <!-- Filter placeholder -->
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        <div class="pattern-grid">
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssinglewporgpatternphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/single-wporg-pattern.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/single-wporg-pattern.php       2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/single-wporg-pattern.php 2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11,7 +11,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> get_header();
</span><span class="cx" style="display: block; padding: 0 10px"> ?>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ <input id="block-data" type="hidden" value="<?php echo rawurlencode( wp_json_encode( get_the_content() ) ); ?>" />
</ins><span class="cx" style="display: block; padding: 0 10px">         <main id="main" class="site-main col-12" role="main">
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                <?php
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                <header class="entry-header">
</span><span class="cx" style="display: block; padding: 0 10px">                                        <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</span><span class="cx" style="display: block; padding: 0 10px">                                        <p>A large hero section with an example background image and a heading in the center.</p>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        <div class="pattern-actions">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 <div id="pattern-actions" class="pattern-actions">
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 <button class="button button-primary">Copy Pattern</button>
</span><span class="cx" style="display: block; padding: 0 10px">                                                <button class="button">Add to favorites</button>
</span><span class="cx" style="display: block; padding: 0 10px">                                        </div>
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentsaddtofavoritebuttonindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/add-to-favorite-button/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/add-to-favorite-button/index.js                         (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/add-to-favorite-button/index.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,10 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+
+const AddToFavoriteButton = () => {
+       return <button className="button">{ __( 'Add to favorites', 'wporg-patterns' ) }</button>;
+};
+
+export default AddToFavoriteButton;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorycontextbarindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/index.js   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/index.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,30 +1,83 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * External dependencies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * WordPress dependencies
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import { useEffect, useRef, useState } from '@wordpress/element';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { useSelect } from '@wordpress/data';
+import { getQueryArg } from '@wordpress/url';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function CategoryContextBar( { message, title, links } ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Internal dependencies
+ */
+import { useRoute } from '../../hooks';
+import { getCategoryFromPath } from '../../utils';
+import { getContextMessage } from './messaging';
+import { store as patternStore } from '../../store';
+
+function CategoryContextBar() {
+       const { path } = useRoute();
</ins><span class="cx" style="display: block; padding: 0 10px">         const [ height, setHeight ] = useState( 0 );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        const [ context, setContext ] = useState( {} );
</ins><span class="cx" style="display: block; padding: 0 10px">         const innerRef = useRef( null );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        const { isAllCategory, category, isLoadingPatterns, patterns } = useSelect(
+               ( select ) => {
+                       const { getCategoryBySlug, getPatternsByQuery, isLoadingPatternsByQuery, getCurrentQuery } = select(
+                               patternStore
+                       );
+                       const categorySlug = getCategoryFromPath( path );
+                       const _category = getCategoryBySlug( categorySlug );
+                       const query = getCurrentQuery();
+
+                       return {
+                               isAllCategory: _category && _category.id === -1,
+                               isLoadingPatterns: isLoadingPatternsByQuery( query ),
+                               patterns: query ? getPatternsByQuery( query ) : [],
+                               category: _category,
+                       };
+               },
+               [ path ]
+       );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         useEffect( () => {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( message ) {
-                       setHeight( innerRef.current.offsetHeight );
-               } else {
-                       setHeight( 0 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! category || isLoadingPatterns ) {
+                       return;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        }, [ message ] );
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                const searchTerm = getQueryArg( path, 'search' );
+
+               let _context = {};
+
+               // Use the category count as default since it has the count of all the associated patterns
+               let count = category.count;
+
+               // If we have a search term use the pattern results length.
+               // Not: This is okay until we start using paging.
+               if ( searchTerm ) {
+                       count = patterns.length;
+               }
+
+               if ( ! isAllCategory || searchTerm ) {
+                       _context = getContextMessage( count, category.name, searchTerm );
+               }
+
+               setContext( _context );
+       }, [ category, isLoadingPatterns, patterns ] );
+
+       useEffect( () => {
+               const _height = context.message ? innerRef.current.offsetHeight : 0;
+               setHeight( _height );
+       }, [ context.message ] );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         return (
</span><span class="cx" style="display: block; padding: 0 10px">                <header className="category-context__bar" style={ { height: `${ height }px` } }>
</span><span class="cx" style="display: block; padding: 0 10px">                        <div ref={ innerRef }>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <h2 className="category-context__bar__copy">{ message }</h2>
-                               { links && links.length > 0 && (
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <h2 className="category-context__bar__copy">{ context.message }</h2>
+                               { context.links && context.links.length > 0 && (
</ins><span class="cx" style="display: block; padding: 0 10px">                                         <div className="category-context__bar__links">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                <h3 className="category-context__bar__title">{ title }</h3>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         <h3 className="category-context__bar__title">{ context.title }</h3>
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                <ul>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                        { links.map( ( i ) => (
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 { context.links.map( ( i ) => (
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                 <li key={ i.href }>
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        <a href={ i.href }>{ i.label }</a>
</span><span class="cx" style="display: block; padding: 0 10px">                                                                </li>
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorycontextbarmessagingjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/messaging.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/messaging.js                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-context-bar/messaging.js 2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,64 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies
+ */
+import { _n, sprintf } from '@wordpress/i18n';
+import { createInterpolateElement } from '@wordpress/element';
+
+/**
+ * Returns an object with extra information about the category.
+ *
+ * @param {number} count Number of patterns associated to the category.
+ * @param {string} categoryName The category name.
+ * @param {string|void} searchTerm The search term.
+ * @return {Object}
+ */
+export const getContextMessage = ( count, categoryName, searchTerm ) => {
+       let message = sprintf(
+               /* translators: %1$d: number of patterns. %2$s category name. */
+               _n( '%1$d <b>%2$s</b> pattern.', '%1$d <b>%2$s</b> patterns.', count, 'wporg-patterns' ),
+               count,
+               categoryName.toLowerCase(),
+               'wporg-patterns'
+       );
+
+       if ( searchTerm ) {
+               if ( categoryName !== 'All' ) {
+                       message = sprintf(
+                               /* translators: %1$d: number of patterns. %2$s category name. %3$s search term  */
+                               _n(
+                                       '%1$d <b>%2$s</b> pattern matching "<b>%3$s</b>".',
+                                       '%1$d <b>%2$s</b> patterns matching "<b>%3$s</b>".',
+                                       count,
+                                       'wporg-patterns'
+                               ),
+                               count,
+                               categoryName.toLowerCase(),
+                               searchTerm,
+                               'wporg-patterns'
+                       );
+               } else {
+                       message = sprintf(
+                               /* translators: %1$d: number of patterns. %2$s search term.  */
+                               _n(
+                                       '%1$d pattern matching "<b>%2$s</b>".',
+                                       '%1$d patterns matching "<b>%2$s</b>".',
+                                       count,
+                                       'wporg-patterns'
+                               ),
+                               count,
+                               searchTerm,
+                               'wporg-patterns'
+                       );
+               }
+       }
+
+       return {
+               message: createInterpolateElement( message, {
+                       b: <b />,
+               } ),
+
+               // TODO Fetch these from somewhere
+               title: '',
+               links: [],
+       };
+};
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorymenudefaultjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/default.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/default.js        2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/default.js  2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -28,7 +28,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        width: activeRef.current.offsetWidth,
</span><span class="cx" style="display: block; padding: 0 10px">                        height: activeRef.current.offsetHeight,
</span><span class="cx" style="display: block; padding: 0 10px">                } );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        }, [ containerRef, activeRef, path ] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( ! isLoading && ! options.length ) {
</span><span class="cx" style="display: block; padding: 0 10px">                return null;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -36,18 +36,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return (
</span><span class="cx" style="display: block; padding: 0 10px">                <ul className={ `category-menu ${ isLoading ? 'category-menu--is-loading' : '' } ` } ref={ containerRef }>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        { options.map( ( i ) => (
-                               <li key={ i.value }>
-                                       <a
-                                               className={ path === i.value ? 'category-menu--is-active' : '' }
-                                               href={ i.value }
-                                               ref={ path === i.value ? activeRef : null }
-                                               onClick={ ( { target } ) => onClick( target.hash ) }
-                                       >
-                                               { i.label }
-                                       </a>
-                               </li>
-                       ) ) }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 { options.map( ( i ) => {
+                               const isActive = path === i.value;
+
+                               return (
+                                       <li key={ i.value }>
+                                               <a
+                                                       className={ isActive ? 'category-menu--is-active' : '' }
+                                                       href={ i.value }
+                                                       ref={ isActive ? activeRef : null }
+                                                       onClick={ onClick }
+                                               >
+                                                       { i.label }
+                                               </a>
+                                       </li>
+                               );
+                       } ) }
</ins><span class="cx" style="display: block; padding: 0 10px">                 </ul>
</span><span class="cx" style="display: block; padding: 0 10px">        );
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorymenumobilejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/mobile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/mobile.js 2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-menu/mobile.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -20,10 +20,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        <ul>
</span><span class="cx" style="display: block; padding: 0 10px">                                { options.map( ( i ) => (
</span><span class="cx" style="display: block; padding: 0 10px">                                        <li key={ i.value }>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                <a href={ i.value } onClick={ () => {
-                                                       setIsOpen( false );
-                                                       onClick( i.value );
-                                               } }>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         <a
+                                                       href={ i.value }
+                                                       onClick={ ( event ) => {
+                                                               setIsOpen( false );
+                                                               onClick( event );
+                                                       } }
+                                               >
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         { i.label }
</span><span class="cx" style="display: block; padding: 0 10px">                                                </a>
</span><span class="cx" style="display: block; padding: 0 10px">                                        </li>
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscategorysearchindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-search/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-search/index.js        2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/category-search/index.js  2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,18 +4,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> import { __ } from '@wordpress/i18n';
</span><span class="cx" style="display: block; padding: 0 10px"> import { Icon, search } from '@wordpress/icons';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-const CategorySearch = ( { isLoading } ) => {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const CategorySearch = ( { defaultValue, isLoading, isVisible, onUpdate, onSubmit } ) => {
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( isLoading ) {
</span><span class="cx" style="display: block; padding: 0 10px">                return <span className="category-search--is-loading" />;
</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 ( ! isVisible ) {
+               return null;
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         return (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                <form method="get" action="/" className="category-search">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         <form method="get" action="/" className="category-search" onSubmit={ onSubmit }>
</ins><span class="cx" style="display: block; padding: 0 10px">                         <label htmlFor="pattern-search" className="screen-reader-text">
</span><span class="cx" style="display: block; padding: 0 10px">                                { __( 'Search for:', 'wporg-patterns' ) }
</span><span class="cx" style="display: block; padding: 0 10px">                        </label>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <input id="pattern-search" type="search" placeholder={ __( 'Search patterns', 'wporg-patterns' ) } />
-                       <button className="category-search__button">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <input
+                               onChange={ onUpdate }
+                               defaultValue={ defaultValue }
+                               id="pattern-search"
+                               type="search"
+                               placeholder={ __( 'Search patterns', 'wporg-patterns' ) }
+                       />
+                       <button type="submit" className="category-search__button">
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <span className="screen-reader-text"> { __( 'Search patterns', 'wporg-patterns' ) }</span>
</span><span class="cx" style="display: block; padding: 0 10px">                                <Icon icon={ search } />
</span><span class="cx" style="display: block; padding: 0 10px">                        </button>
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentscopypatternbuttonindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/copy-pattern-button/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/copy-pattern-button/index.js                            (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/copy-pattern-button/index.js      2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,59 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { Button } from '@wordpress/components';
+
+/**
+ * Uses a hidden textarea that is added and removed from the DOM in order to copy to clipboard via the Browser.
+ *
+ * @param {string} stringToCopy A string that will be copied to the clipboard
+ * @return {boolean} Whether the copy function succeeded
+ */
+const copyToClipboard = ( stringToCopy ) => {
+       const element = document.createElement( 'textarea' );
+
+       // We don't want the text area to be selected since it's temporary.
+       element.setAttribute( 'readonly', '' );
+
+       // We don't want the text area to be visible since it's temporary.
+       element.style.position = 'absolute';
+       element.style.left = '-9999px';
+
+       element.value = stringToCopy;
+
+       document.body.appendChild( element );
+       element.select();
+
+       const success = document.execCommand( 'copy' );
+       document.body.removeChild( element );
+
+       return success;
+};
+
+const CopyPatternButton = ( { onSuccess } ) => {
+       const handleClick = ( { target } ) => {
+               // Grab the pattern markup from hidden input
+               const blockData = document.getElementById( 'block-data' );
+               const blockPattern = JSON.parse( decodeURIComponent( blockData.value ) );
+
+               const success = copyToClipboard( blockPattern );
+
+               // Make sure we reset focus in case it was lost in the 'copy' command.
+               target.focus();
+
+               if ( success ) {
+                       onSuccess();
+               } else {
+                       // TODO Handle error case
+               }
+       };
+
+       return (
+               <Button isPrimary onClick={ handleClick }>
+                       { __( 'Copy Pattern', 'wporg-patterns' ) }
+               </Button>
+       );
+};
+
+export default CopyPatternButton;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid/index.js   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid/index.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -8,29 +8,27 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import PatternThumbnail from '../pattern-thumbnail';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import PatternGridMenu from '../pattern-grid-menu';
</del><span class="cx" style="display: block; padding: 0 10px"> import { store as patternStore } from '../../store';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> function PatternGrid() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        const posts = useSelect( ( select ) => {
-               const { getPatternsByQuery } = select( patternStore );
-               return getPatternsByQuery( {} );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const { posts, isLoading } = useSelect( ( select ) => {
+               const { getPatternsByQuery, isLoadingPatternsByQuery, getCurrentQuery } = select( patternStore );
+               const query = getCurrentQuery();
+
+               return {
+                       posts: query ? getPatternsByQuery( query ) : [],
+                       isLoading: query && isLoadingPatternsByQuery( query ),
+               };
</ins><span class="cx" style="display: block; padding: 0 10px">         } );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // `posts` will be null while the fetch happens.
-       const isLoading = ! Array.isArray( posts );
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                <>
-                       <PatternGridMenu />
-
-                       <div className="pattern-grid">
-                               { isLoading ? (
-                                       <Spinner />
-                               ) : (
-                                       posts.map( ( post ) => <PatternThumbnail key={ post.id } pattern={ post } /> )
-                               ) }
-                       </div>
-               </>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         <div className="pattern-grid">
+                       { isLoading ? (
+                               <Spinner />
+                       ) : (
+                               posts.map( ( post ) => <PatternThumbnail key={ post.id } pattern={ post } /> )
+                       ) }
+               </div>
</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"> 
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridmenuindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/index.js      2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/index.js        2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,10 +1,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * External dependencies
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * WordPress dependencies
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { store as coreStore } from '@wordpress/core-data';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { useDebounce } from '@wordpress/compose';
</ins><span class="cx" style="display: block; padding: 0 10px"> import { useSelect } from '@wordpress/data';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { useEffect, useState } from '@wordpress/element';
-import { getPath } from '@wordpress/url';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { addQueryArgs, getPath, getQueryArg } from '@wordpress/url';
</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">  * Internal dependencies
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -12,67 +11,73 @@
</span><span class="cx" style="display: block; padding: 0 10px"> import CategoryMenu from '../category-menu';
</span><span class="cx" style="display: block; padding: 0 10px"> import CategorySearch from '../category-search';
</span><span class="cx" style="display: block; padding: 0 10px"> import CategoryContextBar from '../category-context-bar';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import contextMessaging from './messaging';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { store as patternStore } from '../../store';
+import { useRoute } from '../../hooks';
+import { removeQueryString } from '../../utils';
</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">  * Module constants
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-const PATTERN_TAXONOMY = 'wporg-pattern-category';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const DEBOUNCE_MS = 300;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> const PatternGridMenu = () => {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Show loading state
-       const [ showLoading, setShowLoading ] = useState( true );
-       const [ isFetching, setIsFetching ] = useState( false );
-       const [ path, setPath ] = useState();
-       const [ categoryContext, setCategoryContext ] = useState( undefined );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const { path, update: updatePath } = useRoute();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        const categories = useSelect( ( select ) =>
-               select( coreStore ).getEntityRecords( 'taxonomy', PATTERN_TAXONOMY )
-       );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const { categories, isLoading, hasLoaded } = useSelect( ( select ) => {
+               const { getCategories, isLoadingCategories, hasLoadedCategories } = select( patternStore );
+               return {
+                       categories: getCategories(),
+                       isLoading: isLoadingCategories(),
+                       hasLoaded: hasLoadedCategories(),
+               };
+       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        useEffect( () => {
-               const pathOnLoad = getPath( window.location.href );
-               setPath( pathOnLoad );
-       }, [] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const handleUpdatePath = ( value ) => {
+               const updatedPath = addQueryArgs( path, {
+                       search: value,
+               } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        useEffect( () => {
-               // Since categories starts as an [] then switches to null
-               if ( showLoading && categories === null ) {
-                       setIsFetching( true );
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         updatePath( updatedPath );
+       };
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( isFetching && Array.isArray( categories ) ) {
-                       setShowLoading( false );
-                       setIsFetching( false );
-               }
-       }, [ isFetching, categories ] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const debouncedHandleUpdate = useDebounce( handleUpdatePath, DEBOUNCE_MS );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        useEffect( () => {
-               setCategoryContext( contextMessaging[ path ] );
-       }, [ path ] );
-
</del><span class="cx" style="display: block; padding: 0 10px">         return (
</span><span class="cx" style="display: block; padding: 0 10px">                <>
</span><span class="cx" style="display: block; padding: 0 10px">                        <nav className="pattern-grid-menu">
</span><span class="cx" style="display: block; padding: 0 10px">                                <CategoryMenu
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        path={ path }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 path={ removeQueryString( path ) }
</ins><span class="cx" style="display: block; padding: 0 10px">                                         options={
</span><span class="cx" style="display: block; padding: 0 10px">                                                categories
</span><span class="cx" style="display: block; padding: 0 10px">                                                        ? categories.map( ( record ) => {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                return {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                        // TODO: This url is temporary and won't use the # symbol
-                                                                       value: `#/pattern-categories/${ record.slug }`,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                 value: `/${ getPath( record.link ) || '' }`,
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         label: record.name,
</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><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        onClick={ ( _path ) => setPath( _path ) }
-                                       isLoading={ showLoading }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 onClick={ ( event ) => {
+                                               event.preventDefault();
+                                               updatePath( event.target.pathname );
+                                       } }
+                                       isLoading={ isLoading }
</ins><span class="cx" style="display: block; padding: 0 10px">                                 />
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <CategorySearch isLoading={ showLoading } />
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <CategorySearch
+                                       isLoading={ isLoading }
+                                       isVisible={ hasLoaded }
+                                       defaultValue={ getQueryArg( window.location.href, 'search' ) }
+                                       onUpdate={ ( event ) => {
+                                               event.preventDefault();
+                                               debouncedHandleUpdate( event.target.value );
+                                       } }
+                                       onSubmit={ ( event ) => {
+                                               event.preventDefault();
+                                               debouncedHandleUpdate( event.target.elements[ 0 ].value );
+                                       } }
+                               />
</ins><span class="cx" style="display: block; padding: 0 10px">                         </nav>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <CategoryContextBar { ...categoryContext } />
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <CategoryContextBar />
</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"> };
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatterngridmenumessagingjs"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/messaging.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/messaging.js  2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-grid-menu/messaging.js    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,39 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
-export default {
-       '#/pattern-categories/header': {
-               message: (
-                       <>
-                               45 <b>Header</b> patterns
-                       </>
-               ),
-               title: 'Related Categories',
-               links: [
-                       {
-                               href: '/pattern-categories/media',
-                               label: 'Media',
-                       },
-                       {
-                               href: '/pattern-categories/blog',
-                               label: 'blog',
-                       },
-               ],
-       },
-       '#/pattern-categories/footer': {
-               message: (
-                       <>
-                               23 <b>Footer</b> patterns that is a very long sentence to check for something.
-                       </>
-               ),
-               title: 'Related Categories',
-               links: [
-                       {
-                               href: '/pattern-categories/media',
-                               label: 'Media',
-                       },
-                       {
-                               href: '/pattern-categories/blog',
-                               label: 'blog',
-                       },
-               ],
-       },
-};
</del></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionscopyguidejs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-guide.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-guide.js                           (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-guide.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,81 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { Animate, Guide } from '@wordpress/components';
+import { createInterpolateElement } from '@wordpress/element';
+
+const CopyPasteImage = () => (
+       // Wrap the image to avoid the UI shift after the GIF loads
+       <div style={ { height: '220px' } }>
+               <img
+                       src="/wp-content/themes/pattern-directory/images/copy-paste-demo.gif"
+                       alt={ __( 'GIF of copy and pasting.', 'wporg-patterns' ) }
+               />
+       </div>
+);
+
+const CopyGuide = ( { onFinish } ) => {
+       return (
+               <Animate type="appear" options={ { origin: 'bottom' } }>
+                       { ( { className } ) => (
+                               <Guide
+                                       className={ `pattern-actions__guide ${ className }` }
+                                       onFinish={ onFinish }
+                                       finishButtonText={ __( 'Close', 'wporg-patterns' ) }
+                                       pages={ [
+                                               {
+                                                       image: <CopyPasteImage />,
+                                                       content: (
+                                                               <div className="pattern-actions__guide-content">
+                                                                       <h3 className="pattern-actions__guide-title">
+                                                                               { __( 'How to use patterns on your WordPress site.', 'wporg-patterns' ) }
+                                                                       </h3>
+                                                                       <p>
+                                                                               { __(
+                                                                                       'Patterns are really just text. And, just like you can copy and paste text, you can copy and paste patterns. Its really easy!',
+                                                                                       'wporg-patterns'
+                                                                               ) }
+                                                                       </p>
+                                                                       <ol>
+                                                                               <li>
+                                                                                       <p>
+                                                                                               { __(
+                                                                                                       'Open any post or page in the WordPress block editor.',
+                                                                                                       'wporg-patterns'
+                                                                                               ) }
+                                                                                       </p>
+                                                                               </li>
+                                                                               <li>
+                                                                                       <p>
+                                                                                               { __(
+                                                                                                       'Place your cursor where you want to add the pattern.',
+                                                                                                       'wporg-patterns'
+                                                                                               ) }
+                                                                                       </p>
+                                                                               </li>
+                                                                               <li>
+                                                                                       <p>
+                                                                                               { createInterpolateElement(
+                                                                                                       __(
+                                                                                                               'Paste the contents of your clipboard by pressing both the <kbd>⌘</kbd> and <kbd>v</kbd> keys, or right-clicking and choose "Paste" from the menu.',
+                                                                                                               'wporg-patterns'
+                                                                                                       ),
+                                                                                                       {
+                                                                                                               kbd: <kbd className="pattern-actions__guide-shortcut" />,
+                                                                                                       }
+                                                                                               ) }
+                                                                                       </p>
+                                                                               </li>
+                                                                       </ol>
+                                                               </div>
+                                                       ),
+                                               },
+                                       ] }
+                               />
+                       ) }
+               </Animate>
+       );
+};
+
+export default CopyGuide;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionscopysuccessmessagejs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-success-message.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-success-message.js                         (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/copy-success-message.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,19 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { Button, Notice } from '@wordpress/components';
+
+const CopySuccessMessage = ( { onClick } ) => (
+       <Notice className="pattern-actions__notice" status="success" isDismissible={ false }>
+               <div>
+                       <b>{ __( 'Pattern copied!', 'wporg-patterns' ) }</b>
+                       { __( ' Now you can paste it into any WordPress post or page.', 'wporg-patterns' ) }
+               </div>
+               <Button onClick={ onClick } isSecondary>
+                       { __( 'Learn More', 'wporg-patterns' ) }
+               </Button>
+       </Notice>
+);
+
+export default CopySuccessMessage;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternpreviewactionsindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/index.js                                (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/pattern-preview-actions/index.js  2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,28 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * External dependencies
+ */
+import { useState } from '@wordpress/element';
+
+/**
+ * Internal dependencies
+ */
+import CopyPatternButton from '../copy-pattern-button';
+import AddToFavoriteButton from '../add-to-favorite-button';
+import CopySuccessMessage from './copy-success-message';
+import CopyGuide from './copy-guide';
+
+const PatternPreviewActions = () => {
+       const [ showSuccess, setShowSuccess ] = useState( false );
+       const [ showGuide, setShowGuide ] = useState( false );
+
+       return (
+               <>
+                       <CopyPatternButton onSuccess={ () => setShowSuccess( true ) } />
+                       <AddToFavoriteButton />
+                       { showSuccess && <CopySuccessMessage onClick={ () => setShowGuide( true ) } /> }
+                       { showGuide && <CopyGuide onFinish={ () => setShowGuide( false ) } /> }
+               </>
+       );
+};
+
+export default PatternPreviewActions;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentspatternsindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/patterns/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/patterns/index.js                               (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/patterns/index.js 2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,19 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Internal dependencies
+ */
+import PatternGrid from '../pattern-grid';
+import PatternGridMenu from '../pattern-grid-menu';
+import QueryMonitor from '../query-monitor';
+import { RouteProvider } from '../../hooks';
+
+const Patterns = () => {
+       return (
+               <RouteProvider>
+                       <QueryMonitor />
+                       <PatternGridMenu />
+                       <PatternGrid />
+               </RouteProvider>
+       );
+};
+
+export default Patterns;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrccomponentsquerymonitorindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/query-monitor/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/query-monitor/index.js                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/components/query-monitor/index.js    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,60 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies
+ */
+import { useEffect } from '@wordpress/element';
+import { useDispatch, useSelect } from '@wordpress/data';
+import { getQueryArgs } from '@wordpress/url';
+
+/**
+ * Internal dependencies
+ */
+import { store as patternStore } from '../../store';
+import { useRoute } from '../../hooks';
+import { getCategoryFromPath } from '../../utils';
+
+/**
+ * Listens for changes to the path and reconstructs the query object based on the path
+ */
+const QueryMonitor = () => {
+       const { path } = useRoute();
+
+       const query = useSelect(
+               ( select ) => {
+                       const { getCategoryBySlug, hasLoadedCategories } = select( patternStore );
+
+                       // We need categories loaded before building the query
+                       if ( ! hasLoadedCategories() ) {
+                               return;
+                       }
+
+                       const categorySlug = getCategoryFromPath( path );
+                       const category = getCategoryBySlug( categorySlug );
+
+                       // Default to {} if empty
+                       const queryStrings = getQueryArgs( path );
+
+                       let _query = queryStrings;
+
+                       // If we have a category and it's not the default category
+                       if ( category && category.id !== -1 ) {
+                               _query = {
+                                       ..._query,
+                                       'pattern-categories': category.id,
+                               };
+                       }
+
+                       return _query;
+               },
+               [ path ]
+       );
+
+       const { setCurrentQuery } = useDispatch( patternStore );
+
+       useEffect( () => {
+               setCurrentQuery( query );
+       }, [ query ] );
+
+       return null;
+};
+
+export default QueryMonitor;
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrchooksindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/index.js                             (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/index.js       2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+export { RouteProvider, useRoute } from './route';
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrchooksroutejs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/route.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/route.js                             (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/hooks/route.js       2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,82 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * WordPress dependencies
+ */
+import { createContext, useContext, useState } from '@wordpress/element';
+import { addQueryArgs, getPathAndQueryString, getQueryArgs } from '@wordpress/url';
+
+/**
+ * Internal dependencies
+ */
+import { removeEmptyArgs, removeQueryString } from '../utils';
+
+const StateContext = createContext();
+
+export function RouteProvider( { children } ) {
+       const [ path, setPath ] = useState( getPathAndQueryString( window.location.href ) );
+
+       /**
+        * Combines query strings from the current path and the new path for arguments with values.
+        *
+        * @param {string} newPath Path including query strings
+        * @return {Object} Query strings as an object
+        */
+       const mergeQueryStrings = ( newPath ) => {
+               const currentQueryStrings = getQueryArgs( path );
+               const newQueryStrings = getQueryArgs( newPath );
+
+               const combined = { ...currentQueryStrings, ...newQueryStrings };
+
+               // remove empty query strings
+               return removeEmptyArgs( combined );
+       };
+
+       /**
+        * Combines the current and new path's query strings and updates the browser's url.
+        *
+        * @param {string} newPath
+        */
+       const _pushState = ( newPath ) => {
+               // Merge the existing and new query strings.
+               const newQueryStrings = mergeQueryStrings( newPath );
+
+               // Remove the query strings from the path
+               const pathOnly = removeQueryString( newPath );
+
+               // Rebuild the full path
+               const rebuiltPath = addQueryArgs( pathOnly, newQueryStrings );
+
+               _replaceState( rebuiltPath );
+       };
+
+       /**
+        * Calls `window.history.pushState` to update the browser's url.
+        *
+        * @param {string} newPath
+        */
+       const _replaceState = ( newPath ) => {
+               window.history.pushState( '', '', newPath );
+               setPath( newPath );
+       };
+
+       return (
+               <StateContext.Provider
+                       value={ {
+                               path: path,
+                               update: _pushState,
+                               replace: _replaceState,
+                       } }
+               >
+                       { children }
+               </StateContext.Provider>
+       );
+}
+
+export function useRoute() {
+       const context = useContext( StateContext );
+
+       if ( context === undefined ) {
+               throw new Error( 'useRoute must be used within a Provider' );
+       }
+
+       return context;
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcindexjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/index.js   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/index.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,7 +7,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import PatternPreview from './components/pattern-preview';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import PatternGrid from './components/pattern-grid';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import PatternPreviewActions from './components/pattern-preview-actions';
+import Patterns from './components/patterns';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> // Load the preview into any awaiting preview container.
</span><span class="cx" style="display: block; padding: 0 10px"> const previewContainers = document.querySelectorAll( '.pattern-preview__container' );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +24,13 @@
</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"> // Load the preview into any awaiting preview container.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-const gridContainer = document.getElementById( 'pattern-grid__container' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const gridContainer = document.getElementById( 'patterns__container' );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( gridContainer ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        render( <PatternGrid />, gridContainer );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ render( <Patterns />, gridContainer );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+// Load the pattern preview actions
+const patternActionsContainer = document.getElementById( 'pattern-actions' );
+if ( patternActionsContainer ) {
+       render( <PatternPreviewActions />, patternActionsContainer );
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreactionsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/actions.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/actions.js   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/actions.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -20,3 +20,32 @@
</span><span class="cx" style="display: block; padding: 0 10px"> export function loadPatterns( query, patterns ) {
</span><span class="cx" style="display: block; padding: 0 10px">        return { type: 'LOAD_BLOCK_PATTERNS', query: query, patterns: patterns };
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Get the action object signalling that the current view has been set.
+ *
+ * @param {string} query Query object.
+ * @return {Object} Action object.
+ */
+export function setCurrentQuery( query ) {
+       return { type: 'SET_CURRENT_QUERY', query: query };
+}
+
+/**
+ * Get the action object signalling that categories have been requested.
+ *
+ * @return {Object} Action object.
+ */
+export function fetchCategories() {
+       return { type: 'FETCH_CATEGORIES' };
+}
+
+/**
+ * Get the action object signalling that categories have been loaded.
+ *
+ * @param {Array} categories A list of categories.
+ * @return {Object} Action object.
+ */
+export function loadCategories( categories ) {
+       return { type: 'LOAD_CATEGORIES', categories: categories };
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstorereducerjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/reducer.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/reducer.js   2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/reducer.js     2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4,6 +4,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> import { combineReducers } from '@wordpress/data';
</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">+ * Internal dependencies
+ */
+import { getAllCategory } from './utils';
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Reducer to track available patterns.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param {Object} state Current state.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -17,6 +22,44 @@
</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">+/**
+ * Reducer to track categories.
+ *
+ * @param {Object} state Current state.
+ * @param {Object} action Dispatched action.
+ * @return {Object} Updated state.
+ */
+export function categories( state = undefined, action ) {
+       switch ( action.type ) {
+               case 'FETCH_CATEGORIES':
+                       return null; // Indicates the query is in progress
+               case 'LOAD_CATEGORIES':
+                       // Sort the categories alphabetically.
+                       // See: https://github.com/WordPress/pattern-directory/pull/76#issuecomment-818330872
+                       const sorted = ( action.categories || [] ).sort( ( a, b ) => a.name.localeCompare( b.name ) );
+
+                       return [ getAllCategory(), ...sorted ];
+       }
+
+       return state;
+}
+
+/**
+ * Reducer to track the current query.
+ *
+ * @param {Object} state Current state.
+ * @param {Object} action Dispatched action.
+ * @return {Object} Updated state.
+ */
+export function currentQuery( state = undefined, action ) {
+       switch ( action.type ) {
+               case 'SET_CURRENT_QUERY':
+                       return action.query;
+       }
+
+       return state;
+}
+
</ins><span class="cx" style="display: block; padding: 0 10px"> function byId( state = {}, action ) {
</span><span class="cx" style="display: block; padding: 0 10px">        const patternsById = ( action.patterns || [] ).reduce( ( acc, cur ) => ( { ...acc, [ cur.id ]: cur } ), {} );
</span><span class="cx" style="display: block; padding: 0 10px">        switch ( action.type ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -39,7 +82,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> export default combineReducers( {
</span><span class="cx" style="display: block; padding: 0 10px">        patterns,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // taxonomy items,
-       // filter query,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ categories,
+       currentQuery,
</ins><span class="cx" style="display: block; padding: 0 10px">         // favorites,
</span><span class="cx" style="display: block; padding: 0 10px"> } );
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreresolversjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/resolvers.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/resolvers.js 2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/resolvers.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -7,7 +7,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { fetchPatterns, loadPatterns } from './actions';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { fetchCategories, fetchPatterns, loadCategories, loadPatterns } from './actions';
</ins><span class="cx" style="display: block; padding: 0 10px"> import { getQueryString } from './utils';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> export function* getPatternsByQuery( query ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -20,3 +20,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                yield loadPatterns( queryString, results );
</span><span class="cx" style="display: block; padding: 0 10px">        } catch ( error ) {}
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+export function* getCategories() {
+       try {
+               yield fetchCategories();
+               const results = yield apiFetch( {
+                       path: addQueryArgs( '/wp/v2/pattern-categories' ),
+               } );
+               yield loadCategories( results );
+       } catch ( error ) {}
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreselectorsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/selectors.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/selectors.js 2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/selectors.js   2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -51,3 +51,64 @@
</span><span class="cx" style="display: block; padding: 0 10px"> export function getPattern( state, id ) {
</span><span class="cx" style="display: block; padding: 0 10px">        return state.patterns.byId[ id ] || null;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Get the current query.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {Object} The current query.
+ */
+export function getCurrentQuery( state ) {
+       return state.currentQuery;
+}
+
+/**
+ * Check if there is a pending request for category query.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {boolean} True if an API request is in progress for this query.
+ */
+export function isLoadingCategories( state ) {
+       return state.categories === null;
+}
+
+/**
+ * Check if the categories have been loaded.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {boolean} True if categories is an array.
+ */
+export function hasLoadedCategories( state ) {
+       return Array.isArray( state.categories );
+}
+
+/**
+ * Get all loaded categories.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {Array} A list of all categories.
+ */
+export function getCategories( state ) {
+       return state.categories;
+}
+
+/**
+ * Get category by its slug.
+ *
+ * @param {Object} state Global application state.
+ * @param {string} slug Category slug.
+ *
+ * @return {Array|undefined} The requested category.
+ */
+export function getCategoryBySlug( state, slug ) {
+       if ( ! hasLoadedCategories( state ) ) {
+               return;
+       }
+
+       const [ cat ] = state.categories.filter( ( i ) => i.slug === slug );
+       return cat;
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestfixturescategoriesjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/fixtures/categories.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/fixtures/categories.js                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/fixtures/categories.js    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,38 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+export default [
+       {
+               id: 2,
+               count: 0,
+               description: '',
+               link: 'pattern-categories/all/',
+               name: 'All',
+               slug: 'all',
+               taxonomy: 'wporg-pattern-category',
+               parent: 0,
+               meta: [],
+               _links: {
+                       self: [ { href: 'wp-json/wp/v2/pattern-categories/2' } ],
+                       collection: [ { href: 'wp-json/wp/v2/pattern-categories' } ],
+                       about: [ { href: 'wp-json/wp/v2/taxonomies/wporg-pattern-category' } ],
+                       'wp:post_type': [ { href: 'wp-json/wp/v2/wporg-pattern?pattern-categories=2' } ],
+                       curies: [ { name: 'wp', href: 'https://api.w.org/{rel}', templated: true } ],
+               },
+       },
+       {
+               id: 3,
+               count: 0,
+               description: '',
+               link: 'pattern-categories/header/',
+               name: 'Header',
+               slug: 'header',
+               taxonomy: 'wporg-pattern-category',
+               parent: 0,
+               meta: [],
+               _links: {
+                       self: [ { href: 'wp-json/wp/v2/pattern-categories/3' } ],
+                       collection: [ { href: 'wp-json/wp/v2/pattern-categories' } ],
+                       about: [ { href: 'wp-json/wp/v2/taxonomies/wporg-pattern-category' } ],
+                       'wp:post_type': [ { href: 'wp-json/wp/v2/wporg-pattern?pattern-categories=3' } ],
+                       curies: [ { name: 'wp', href: 'https://api.w.org/{rel}', templated: true } ],
+               },
+       },
+];
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestreducerjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/reducer.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/reducer.js      2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/reducer.js        2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3,7 +3,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import apiPatterns from './fixtures/patterns';
</span><span class="cx" style="display: block; padding: 0 10px"> import apiPatternsPage2 from './fixtures/patterns-page-2';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { patterns } from '../reducer';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import apiCategories from './fixtures/categories';
+import { categories, patterns } from '../reducer';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> describe( 'state', () => {
</span><span class="cx" style="display: block; padding: 0 10px">        describe( 'patterns', () => {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -58,4 +59,31 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        expect( state.byId ).toHaveProperty( '15' );
</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">+
+       describe( 'categories', () => {
+               it( 'should return null when fetching categories', () => {
+                       const state = categories(
+                               {},
+                               {
+                                       type: 'FETCH_CATEGORIES',
+                               }
+                       );
+
+                       expect( state ).toBeNull();
+               } );
+
+               it( 'should store categories in the state with the "all" category', () => {
+                       const state = categories(
+                               {},
+                               {
+                                       type: 'LOAD_CATEGORIES',
+                                       categories: apiCategories,
+                               }
+                       );
+
+                       const lengthWithAll = apiCategories.length + 1;
+
+                       expect( state ).toHaveLength( lengthWithAll );
+               } );
+       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> } );
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestresolversjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/resolvers.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/resolvers.js    2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/resolvers.js      2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,7 +2,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import apiPatterns from './fixtures/patterns';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { getPatternsByQuery } from '../resolvers';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import apiCategories from './fixtures/categories';
+import { getCategories, getPatternsByQuery } from '../resolvers';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> describe( 'getPatternsByQuery', () => {
</span><span class="cx" style="display: block; padding: 0 10px">        it( 'yields with the requested patterns', async () => {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -29,3 +30,25 @@
</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">+describe( 'getCategories', () => {
+       it( 'yields with the requested patterns', async () => {
+               const generator = getCategories();
+
+               expect( generator.next().value ).toEqual( {
+                       type: 'FETCH_CATEGORIES',
+               } );
+
+               // trigger apiFetch
+               const { value: apiFetchAction } = generator.next();
+               expect( apiFetchAction.request ).toEqual( {
+                       path: '/wp/v2/pattern-categories',
+               } );
+
+               // Provide response and trigger action
+               const { value: received } = generator.next( apiCategories );
+               expect( received ).toEqual( {
+                       type: 'LOAD_CATEGORIES',
+                       categories: apiCategories,
+               } );
+       } );
+} );
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoretestselectorsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/selectors.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/selectors.js    2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/test/selectors.js      2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2,7 +2,18 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * Internal dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import apiPatterns from './fixtures/patterns';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-import { getPattern, getPatterns, getPatternsByQuery, isLoadingPatternsByQuery } from '../selectors';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import apiCategories from './fixtures/categories';
+import {
+       getCategories,
+       getCategoryBySlug,
+       getCurrentQuery,
+       getPattern,
+       getPatterns,
+       getPatternsByQuery,
+       hasLoadedCategories,
+       isLoadingCategories,
+       isLoadingPatternsByQuery,
+} from '../selectors';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> describe( 'selectors', () => {
</span><span class="cx" style="display: block; padding: 0 10px">        const initialState = {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -90,4 +101,116 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        expect( pattern ).toHaveProperty( 'title.rendered', 'Large header with a heading' );
</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">+
+       describe( 'getCurrentQuery', () => {
+               it( 'should get an empty object if there is no query', () => {
+                       const initialQueryState = {
+                               currentQuery: {},
+                       };
+
+                       expect( getCurrentQuery( initialQueryState ) ).toMatchObject( {} );
+               } );
+
+               it( 'should get an the correct query object', () => {
+                       const initialQueryState = {
+                               currentQuery: {
+                                       'pattern-categories': [ 1 ],
+                               },
+                       };
+
+                       expect( getCurrentQuery( initialQueryState ) ).toMatchObject( initialQueryState.currentQuery );
+               } );
+       } );
+
+       describe( 'isLoadingCategories', () => {
+               it( 'should get true when state is null', () => {
+                       const categoryState = {
+                               categories: null,
+                       };
+
+                       expect( isLoadingCategories( categoryState ) ).toBe( true );
+               } );
+
+               it( 'should get false when state is an array', () => {
+                       const categoryState = {
+                               categories: apiCategories,
+                       };
+                       expect( isLoadingCategories( categoryState ) ).toBe( false );
+               } );
+       } );
+
+       describe( 'hasLoadedCategories', () => {
+               it( 'should get false when state is undefined', () => {
+                       const categoryState = {
+                               categories: undefined,
+                       };
+                       expect( hasLoadedCategories( categoryState ) ).toBe( false );
+               } );
+
+               it( 'should get true when state is an array', () => {
+                       const categoryState = {
+                               categories: apiCategories,
+                       };
+                       expect( hasLoadedCategories( categoryState ) ).toBe( true );
+               } );
+       } );
+
+       describe( 'getCategories', () => {
+               it( 'should get a list of categories', () => {
+                       const categoryState = {
+                               categories: apiCategories,
+                       };
+
+                       expect( getCategories( categoryState ) ).toHaveLength( apiCategories.length );
+               } );
+       } );
+
+       describe( 'getCategoryBySlug', () => {
+               it( 'should get undefined if categories have not loaded', () => {
+                       expect(
+                               getCategoryBySlug(
+                                       {
+                                               categories: undefined,
+                                       },
+                                       'header'
+                               )
+                       ).toBeUndefined();
+
+                       expect(
+                               getCategoryBySlug(
+                                       {
+                                               categories: null,
+                                       },
+                                       'header'
+                               )
+                       ).toBeUndefined();
+               } );
+
+               it( 'should get undefined if there are no categories', () => {
+                       const categoryState = {
+                               categories: [],
+                       };
+
+                       expect( getCategoryBySlug( categoryState, apiCategories[ 0 ].slug ) ).toBeUndefined();
+               } );
+
+               it( 'should get undefined if no category exist', () => {
+                       const categoryState = {
+                               categories: apiCategories,
+                       };
+
+                       expect( getCategoryBySlug( categoryState, 'missing-category-slug' ) ).toBeUndefined();
+               } );
+
+               it( 'should get the correct category', () => {
+                       const categoryState = {
+                               categories: apiCategories,
+                       };
+
+                       expect( getCategoryBySlug( categoryState, apiCategories[ 0 ].slug ) ).toHaveProperty(
+                               'id',
+                               apiCategories[ 0 ].id
+                       );
+               } );
+       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> } );
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcstoreutilsjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/utils.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/utils.js     2021-04-26 04:01:47 UTC (rev 10923)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/store/utils.js       2021-04-26 17:12:15 UTC (rev 10924)
</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">  * WordPress dependencies
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> import { addQueryArgs } from '@wordpress/url';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { __ } from '@wordpress/i18n';
</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">  * Convert a query object into a standardized string.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -38,3 +39,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return stableKey;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Get the first category used to display all patterns.
+ *
+ * See Schema:
+ * https://developer.wordpress.org/rest-api/reference/categories/
+ *
+ * @return {Object} A category object
+ */
+export function getAllCategory() {
+       return {
+               id: -1,
+               slug: '', // Slug matches url
+               name: __( 'All', 'wporg-patterns' ),
+               link: '/',
+       };
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilscategoryjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/category.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/category.js                          (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/category.js    2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,54 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Remove the last '/' from a string if it exists.
+ *
+ * @param {string} str Url or url part
+ * @return {string}
+ */
+const removeTrailingSlash = ( str ) => {
+       return str.replace( /\/$/, '' );
+};
+
+/**
+ * Removes any empty properties or empty strings.
+ *
+ * @param {Object} obj
+ * @return {Object} Object with keys that are defined and not empty
+ */
+export const removeEmptyArgs = ( obj ) => {
+       const cleaned = {};
+
+       Object.keys( obj ).forEach( ( key ) => {
+               const arg = obj[ key ];
+
+               // If it's not undefined or null convert it to string and check that it is not empty.
+               // It's a bit of a "trick" to handle non-strings and strings without checking type explicitly.
+               if ( arg !== undefined && arg !== null && arg.toString().length > 0 ) {
+                       cleaned[ key ] = arg;
+               }
+       } );
+
+       return cleaned;
+};
+
+/**
+ * Splits a string at ? and returns the first part.
+ *
+ * @param {string} path Url or url part
+ * @return {string} Returns string or string before ? character.
+ */
+export const removeQueryString = ( path ) => {
+       return path.split( '?' )[ 0 ];
+};
+
+/**
+ * Retrieves the category from a url path without query string params.
+ *
+ * @param {string} path
+ * @return {string} The category slug.
+ */
+export const getCategoryFromPath = ( path ) => {
+       let _path = removeQueryString( path );
+       _path = removeTrailingSlash( _path );
+
+       return _path.substring( _path.lastIndexOf( '/' ) + 1 );
+};
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilsindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/index.js                             (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/index.js       2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+export { getCategoryFromPath, removeQueryString, removeEmptyArgs } from './category';
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentthemespubwporgpatternssrcutilstestindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/test/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/test/index.js                                (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/themes/pub/wporg-patterns/src/utils/test/index.js  2021-04-26 17:12:15 UTC (rev 10924)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,58 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+import { getCategoryFromPath, removeEmptyArgs, removeQueryString } from '../index';
+
+describe( 'utils', () => {
+       describe( 'getCategoryFromPath', () => {
+               it( 'should return empty string if path is empty', async () => {
+                       expect( getCategoryFromPath( '' ) ).toEqual( '' );
+               } );
+
+               it( 'should return empty string if path is "/"', async () => {
+                       expect( getCategoryFromPath( '/' ) ).toEqual( '' );
+               } );
+
+               it( 'should correctly return category', async () => {
+                       expect( getCategoryFromPath( 'patterns-categories/header' ) ).toEqual( 'header' );
+                       expect( getCategoryFromPath( '/patterns-categories/header' ) ).toEqual( 'header' );
+                       expect( getCategoryFromPath( '/patterns-categories/header/' ) ).toEqual( 'header' );
+                       expect( getCategoryFromPath( '/patterns-categories/subdirectory/header/' ) ).toEqual( 'header' );
+                       expect( getCategoryFromPath( '/patterns-categories/subdirectory/header/?search=test' ) ).toEqual(
+                               'header'
+                       );
+               } );
+       } );
+
+       describe( 'removeQueryString', () => {
+               it( 'should return the path if there is no query string', async () => {
+                       const path = '/path/without/string';
+
+                       expect( removeQueryString( path ) ).toEqual( path );
+               } );
+
+               it( 'should return the path if there is a query string', async () => {
+                       const base = '/path/without/string';
+                       const path = `${ base }?search=keyword`;
+
+                       expect( removeQueryString( path ) ).toEqual( base );
+               } );
+       } );
+
+       describe( 'removeEmptyArgs', () => {
+               it( 'should remove empty properties', async () => {
+                       const shouldReturn = {
+                               string_1: 'first value',
+                               string_2: 'second value',
+                               boolean: false,
+                       };
+
+                       const obj = {
+                               ...shouldReturn,
+                               empty_string: '',
+                               undefined: undefined,
+                               null: null,
+                       };
+
+                       expect( removeEmptyArgs( {} ) ).toMatchObject( {} );
+                       expect( removeEmptyArgs( obj ) ).toMatchObject( shouldReturn );
+               } );
+       } );
+} );
</ins></span></pre>
</div>
</div>

</body>
</html>